提振.MultiArray作为类的成员:调整大小和复制断言崩溃
Boost.MultiArray as a member of a class: resize and copy assertion crash
为了说明这个问题,假设您有一个名为basic_ma的类,并且有一个成员是MultiArray (MA)。还假设在构造函数(或方法)中,您在临时MA(此处称为tmp
)中进行了一些计算,并且您想将tmp
的内容复制到ma
(此行为是所需的,我希望同时拥有tmp
和ma
)。
// 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
};
现在考虑另一个类,其成员是前一个类。
// 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;
};
当我使用带有两个参数的构造函数实例化group_ma
时,出现了断言问题:
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
:
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;
}
使用gcc version 6.2.1
:
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;
}
错误信息指出在赋值过程中数组的大小不相同。有几种方法可以解决这个问题。在group_ma中使用构造函数:
group_ma(size_t x, size_t y)
:bma1( x, y )
,bma2( y, x )
{
//bma1 = basic_ma(x, y);
bma1.show();
//bma2 = basic_ma(y, x);
bma2.show();
}
默认构造函数没有给你一个3x3。Boost文档讨论了调整multi_array的大小,如果你必须分配,你可以这样做。但需要注意的是,尺寸保持不变。
添加成员到basic_ma
void resize(size_t x, size_t y )
{
ma.resize( boost::extents[x][y] );
}
:
basic_ma not_initialized;
not_initialized.resize( 3, 3 );
basic_ma bma(3,3);
bma.show();
not_initialized= bma; // now this works
not_initialized.show( );
另一种想法是,你可以在自己的赋值操作符中进行大小调整…
所以如果你想让basic_ma
保持私有。使group_ma
成为basic_ma
的朋友。然后你可以把它添加到group_ma
void operator = ( group_ma& source )
{
bma1.resize( source.bma1.ma.shape( )[ 0 ], source.bma1.ma.shape( )[ 1 ] );
bma2.resize( source.bma2.ma.shape( )[ 0 ], source.bma2.ma.shape( )[ 1 ] );
bma1= source.bma1;
bma2= source.bma2;
}
group_ma gma1;
gma1 = group_ma(3, 3);
group_ma gma2(4, 2);
gma1= gma2;
也许有更好的方法,我不知道,因为我没有看过。但我认为这可能适合你。
如果你有不同类型的组,那就更好了。在basic_ma
的赋值操作符中调整大小。然后在组分配中你只需要:
void operator = ( group_ma& source )
{
bma1= source.bma1;
bma2= source.bma2;
}
相关文章:
- 如何修复条件复制期间发生的崩溃
- 复制赋值构造函数中的aligned_alloc内存块在释放时崩溃
- 程序崩溃在复制构造函数上
- 为什么在复制构造函数中分配联合成员会崩溃
- C++初始化复制构造函数中的列表赋值,并在复制构造函数中崩溃
- C :复制构造函数崩溃
- QT应用程序崩溃但不容易复制,我捕获了转储堆栈以及如何通过堆栈找到源代码
- 根据条件将元素从 std::vector 复制到 std::set 但它崩溃了
- 矢量未正确擦除内容(复制分配运算符的量运行直到崩溃 [BEX])
- 尝试复制数组时从 DLL 调用函数时程序崩溃
- 双向链表复制构造函数和程序崩溃
- 复制构造函数动机 - 为什么我的程序不崩溃?
- 复制数组 - 将数组加倍后崩溃
- 在类中复制和存储 LPTSTR 会导致崩溃
- 复制提升::跨线程崩溃的异常
- 复制特定类时崩溃
- 复制列表时光荣崩溃
- clang与gcc运行时的区别:用clang构建的c++类模板在没有复制构造函数的情况下崩溃,用复制构造函数构建的gcc
- visual String使用c++中的指针进行复制,在复制过程中程序崩溃
- 当绕过c++中的函数从目标进程的ExtTextOut复制数据字符串时,malloc会导致崩溃吗?