C++ 库研究笔记——拷贝构造函数的一个错误范例

来源:互联网 发布:慢摇吧软件 编辑:程序博客网 时间:2024/04/29 12:45

之前记录的有:

 

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];        }    }





原创粉丝点击