問題を表示するには、basic_maというクラスがあり、MultiArray(MA)というメンバーがあるとします。また、コンストラクタ(またはメソッド)で、MA(ここではtmp
と呼ばれます)の計算があり、tmp
の内容をma
にコピーしたいとします(この動作が望まれます。同じ時刻tmp
およびma
)。クラスのメンバーとしてのBoost.MultiArray:サイズ変更およびコピーアサーションのクラッシュ
// A class with a MultiArray member
class basic_ma {
public:
basic_ma() { }
// initialize ma
basic_ma(size_t x, size_t y) {
// I would like to compute in tmp and then copy to member ma
array2d tmp(boost::extents[x][y]);
// dummy stuff, some serious calculation in real life
for(size_t i=0; i<tmp.shape()[0]; ++i) {
for(size_t j=0; j<tmp.shape()[1]; ++j) {
tmp[i][j] = (i+1.0)*(j+1.0);
}
}
ma.resize(boost::extents[tmp.shape()[0]][tmp.shape()[1]]);
ma = tmp;
// Alternative function to copy
//copy_ma(tmp, ma);
}
void show() {
cout << endl << "> Show ma" << endl;
for(size_t i = 0; i < ma.shape()[0]; ++i) {
cout << "> ";
for(size_t j = 0; j < ma.shape()[1]; ++j) {
cout << ma[i][j] << '\t';
}
cout << endl;
}
cout << endl;
}
private:
array2d ma;// MultiArray member
};
メンバーが以前のクラスである別のクラスを検討してください。私は2つのパラメータを持つコンストラクタを使用してgroup_ma
をインスタンス化するとき
// Another class has several (possibly a vector of) basic_ma's
class group_ma {
public:
group_ma() { }
// constructs basic_ma's
group_ma(size_t x, size_t y) {
bma1 = basic_ma(x, y);
bma1.show();
bma2 = basic_ma(y, x);
bma2.show();
}
private:
basic_ma bma1;
basic_ma bma2;
};
そして、アサーションの問題が発生します。ここでは
a.out: /usr/include/boost/multi_array/multi_array_ref.hpp:484: boost::multi_array_ref<T, NumDims>& boost::multi_array_ref<T, NumDims>::operator=(const ConstMultiArray&) [with ConstMultiArray = boost::multi_array<double, 2ul>; T = double; long unsigned int NumDims = 2ul]: Assertion `std::equal(other.shape(),other.shape()+this->num_dimensions(), this->shape())' failed.
Aborted (core dumped)
はmain
です:
gcc version 6.2.1
でコンパイル
int main(int argc, char **argv) {
basic_ma bma(3,5);// OK compile and run
bma.show();// OK compile and run
group_ma gma1;// OK compile and run
gma1 = group_ma(3, 3);// Compile but assertion error when running
group_ma gma2(4, 2);// Compile but assertion error when running
unique_ptr<group_ma> gma_ptr = unique_ptr<group_ma>(new group_ma(5, 6));
// Compile but assertion error when running
return 0;
}
:
g++ main.cpp -std=gnu++11 -pedantic -Wall
basic_ma
が問題なく動作し、group_ma
を使用すると問題が発生します。 私も同じ結果とMAさんをコピーするために別の機能を試してみました:私は私が間違ってやっているものを見ていない
// copy Boost.MultiArray source to dest
void copy_ma(const array2d source, array2d& dest) {
vector<size_t> grid;
const size_t* shape = source.shape();
grid.assign(shape, shape+source.num_dimensions());
dest.resize(grid);
for(size_t i=0; i<source.shape()[0]; ++i) {
for(size_t j=0; j<source.shape()[1]; ++j) {
dest[i][j] = source[i][j];
}
}
}
。 -DNDEBUG
フラグを使用 は、メモリエラーが発生:malloc(): memory corruption (fast)
コード全体はここにある:
#include <iostream>
#include <boost/multi_array.hpp>
#include <memory>
using namespace std;
typedef boost::multi_array<double, 2> array2d;
// A class with a MultiArray member
class basic_ma {
public:
basic_ma() { }
// initialize ma
basic_ma(size_t x, size_t y) {
// I would like to compute in tmp and the copy to member ma
array2d tmp(boost::extents[x][y]);
// dummy stuff
for(size_t i=0; i<tmp.shape()[0]; ++i) {
for(size_t j=0; j<tmp.shape()[1]; ++j) {
tmp[i][j] = (i+1.0)*(j+1.0);
}
}
ma.resize(boost::extents[tmp.shape()[0]][tmp.shape()[1]]);
ma = tmp;
// Alternative function to copy
// copy_ma(tmp, ma);
}
void show() {
cout << endl << "> Show ma" << endl;
for(size_t i = 0; i < ma.shape()[0]; ++i) {
cout << "> ";
for(size_t j = 0; j < ma.shape()[1]; ++j) {
cout << ma[i][j] << '\t';
}
cout << endl;
}
cout << endl;
}
private:
array2d ma;// MultiArray member
};
// copy Boost.MultiArray source to dest
void copy_ma(const array2d source, array2d& dest) {
vector<size_t> grid;
const size_t* shape = source.shape();
grid.assign(shape, shape+source.num_dimensions());
dest.resize(grid);
for(size_t i=0; i<source.shape()[0]; ++i) {
for(size_t j=0; j<source.shape()[1]; ++j) {
dest[i][j] = source[i][j];
}
}
}
// Another class will have several (possibly a vector of) basic_ma's
class group_ma {
public:
group_ma() { }
// constructs basic_ma's
group_ma(size_t x, size_t y) {
bma1 = basic_ma(x, y);
bma1.show();
bma2 = basic_ma(y, x);
bma2.show();
}
private:
basic_ma bma1;
basic_ma bma2;
};
int main(int argc, char **argv) {
basic_ma bma(3,5);// OK compile and run
bma.show();// OK compile and run
group_ma gma1;// OK compile and run
gma1 = group_ma(3, 3);// Compile but assertion error when running
group_ma gma2(4, 2);// Compile but assertion error when running
unique_ptr<group_ma> gma_ptr = unique_ptr<group_ma>(new group_ma(5, 6));
// Compile but assertion error when running
return 0;
}
です。あなたが 'bma1 = basic_ma(x、y);を指摘したように'は動作しません。別の回避策は、移動代入演算子 'basic_ma&operator =(const basic_ma && other_bma)'を実装することです。私の具体的なアプリケーションでは、 'basic_ma'のコンストラクタを直接呼び出すことができないので、それはより適していると思います。しかし、まだ100%確実ではありません。 – Caos21