Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/143.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 复制构造函数内存泄漏_C++_Constructor_Destructor_Copy Constructor - Fatal编程技术网

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