之前记录的有:
C++库研究笔记——赋值操作符operator=的正确重载方式(三个准则)
我原来的拷贝构造函数是这样写的:
explicit array1d(Index size=0,T val=T())
:size_(size),data_(0)
{
log_info("construct 1");
if(size==0)
return;
allocate(); // allocate memory
for(int i=0; i<size_; i++){
data_[i]=val;
}
}
// 这样写的本意是:为了能够使用 std::vector<T> v_other; array1d<T> v(v_other);
template<class ArrayType>
array1d(const ArrayType& other)
{
log_info("arrayType");
size_= other.size();
allocate();
// copy value
for(int i=0; i<size_; i++){
data_[i]=other[i];
}
}
std::vector<real> v(3,9.0);
array1d<real> b(v);
b.print();
确实没有问题
但是:
array1d<float, long> dl(9l);
dl[3]=4;
dl.print("dl");
//
array1d<float, long> dl2(dl);
dl2.print("dl2");
编译没有问题,运行时会出现,double free memory
*** glibc detected *** ./main: double free or corruption (fasttop): 0x0000000001b85010 ***
通过追踪发现:
上面的代码根本没有调用
template<class ArrayType>
array1d(const ArrayType& other)
{
log_info("arrayType");
size_= other.size();
allocate();
// copy value
for(int i=0; i<size_; i++){
data_[i]=other[i];
}
}
而是,
直接原始的拷贝,这样就会拷贝一个相同的数据指针位置,然后在相同的位置释放两次内存
解决办法:(追加如下代码)
array1d(const array1d & other)
{
log_info("array1d&");
size_= other.size();
allocate();
// copy value
for(int i=0; i<size_; i++){
data_[i]=other[i];
}
}