C++ 复制构造函数内存泄漏
我正在努力学习编写自定义构造函数的基础知识,但我不知道自己做错了什么。我知道,就我的目的而言,让编译器完成它的工作就足够了,但我很好奇如何修复我的定义C++ 复制构造函数内存泄漏,c++,constructor,destructor,copy-constructor,C++,Constructor,Destructor,Copy Constructor,我正在努力学习编写自定义构造函数的基础知识,但我不知道自己做错了什么。我知道,就我的目的而言,让编译器完成它的工作就足够了,但我很好奇如何修复我的定义 #include <iostream> #include <stdexcept> class Matrix { public: Matrix(int rows, int cols); //my custom constructor ~Matrix();
#include <iostream>
#include <stdexcept>
class Matrix {
public:
Matrix(int rows, int cols); //my custom constructor
~Matrix(); //my custom destructor
Matrix(const Matrix& m); //my custom copy constructor
Matrix& operator= (const Matrix& m); //my custom assignment operator
private:
int rows_, cols_;
double* data_;
};
Matrix::Matrix(int rows, int cols): rows_ (rows), cols_ (cols){
if (rows == 0 || cols == 0)
throw std::out_of_range("Matrix constructor has 0 size");
data_ = new double[rows * cols];
}
Matrix::~Matrix()
{
delete[] data_;
}
Matrix::Matrix(const Matrix& m) : rows_(m.rows_), cols_(m.cols_)
{
data_ = new double[rows_ * cols_];
data_=m.data_;
}
Matrix& Matrix::operator=(const Matrix& m){
if(this != &m){
double* newdata_=new double[m.cols_*m.rows_];
*newdata_=*data_;
delete[] data_;
data_=newdata_;
rows_=m.rows_;
cols_=m.cols_;
}
return *this;
}
运行可执行文件时的错误是:
free():在tcache 2中检测到双重空闲
我认为复制构造函数和赋值运算符都不会导致调用析构函数,对吗?为什么会这样?基本问题是,在复制构造函数中分配内存后,您没有复制数据
Matrix::Matrix(const Matrix& m) : rows_(m.rows_), cols_(m.cols_)
{
data_ = new double[rows_ * cols_];
data_ = m.data_; // <-- This is wrong
}
还有一个错误,那就是赋值运算符。您正在犯同样的错误,错误地使用
=
进行复制,而不是使用必要的函数在两个缓冲区之间进行数据复制
Matrix& Matrix::operator=(const Matrix& m)
{
if(this != &m)
{
double* newdata_=new double[m.cols_*m.rows_];
*newdata_=*data_; // <-- This does not copy the data
//
基本上是制作一个副本,然后我们用副本的数据交换当前对象的数据。然后,复制会随着旧数据一起消失。基本问题是,在复制构造函数中分配内存后,您没有复制数据
Matrix::Matrix(const Matrix& m) : rows_(m.rows_), cols_(m.cols_)
{
data_ = new double[rows_ * cols_];
data_ = m.data_; // <-- This is wrong
}
还有一个错误,那就是赋值运算符。您正在犯同样的错误,错误地使用
=
进行复制,而不是使用必要的函数在两个缓冲区之间进行数据复制
Matrix& Matrix::operator=(const Matrix& m)
{
if(this != &m)
{
double* newdata_=new double[m.cols_*m.rows_];
*newdata_=*data_; // <-- This does not copy the data
//
基本上是制作一个副本,然后我们用副本的数据交换当前对象的数据。然后,副本与旧数据一起消失。
*data\u=*m.data\u
将只复制数组第一个元素的值,对吗?实际上,这种情况下,仅仅让编译器完成它的工作是不够的,因为它不会执行数据的深度复制代码>复制指针,而不是数组的值<代码>*新数据=*数据代码>也没有完成数组的完整复制。在一些地方,你从来没有真正从m
复制过值:你的复制构造函数没有在LHS中设置行或列,你也从来没有在赋值操作符中访问m.data。因此,内存泄漏和双重删除的发生是因为实际上没有复制数组;数据=m.data代码>--您可以在连续的行中执行此操作。您已经在第一行中分配了数据,但第二行通过再次更改data\uuu
来清除所有这些数据。所以很明显这是错误的。这行是不是代码>在复制构造函数中,代码中实际包含的内容是什么?与副本分配的*newdata\=*data\代码>。(并不是说拷贝分配做得很正确,尽管它成功地避免了双重空闲…)您希望这行代码能完成什么?*data\uuux=*m.data\ux
将只复制数组第一个元素的值,对吗?实际上,这种情况下,仅仅让编译器完成它的工作是不够的,因为它不会执行数据的深度复制代码>复制指针,而不是数组的值<代码>*新数据=*数据代码>也没有完成数组的完整复制。在一些地方,你从来没有真正从m
复制过值:你的复制构造函数没有在LHS中设置行或列,你也从来没有在赋值操作符中访问m.data。因此,内存泄漏和双重删除的发生是因为实际上没有复制数组;数据=m.data代码>--您可以在连续的行中执行此操作。您已经在第一行中分配了数据,但第二行通过再次更改data\uuu
来清除所有这些数据。所以很明显这是错误的。这行是不是代码>在复制构造函数中,代码中实际包含的内容是什么?与副本分配的*newdata\=*data\代码>。(并不是说拷贝分配做得很正确,尽管它成功地避免了双重自由…)您希望这行代码能完成什么?
Matrix& Matrix::operator=(const Matrix& m)
{
if(this != &m)
{
Matrix temp(m); // <-- Copy is made
std::swap(temp.data_, data_);
std::swap(temp.rows_, rows_);
std::swap(temp.cols_, cols_);
}
return *this;
}