Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/147.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++_Matrix_Destructor - Fatal编程技术网

C++ 析构函数立即调用并删除我的数组

C++ 析构函数立即调用并删除我的数组,c++,matrix,destructor,C++,Matrix,Destructor,我正在为一个CS项目开发一个矩阵类,我正在尝试开发构造函数。该项目调用两个不同的构造函数,一个只调用行数和列数,使它们都为0,另一个使用初始值设定项列表来分配值。到目前为止,头文件是: typedef unsigned int uint; typedef std::initializer_list<std::initializer_list<double>> i_list; class Matrix { public: double ** arr; uint mainR

我正在为一个CS项目开发一个矩阵类,我正在尝试开发构造函数。该项目调用两个不同的构造函数,一个只调用行数和列数,使它们都为0,另一个使用初始值设定项列表来分配值。到目前为止,头文件是:

typedef unsigned int uint;
typedef std::initializer_list<std::initializer_list<double>> i_list;

class Matrix {
public:
double ** arr;
uint mainRows;
uint mainCols;

Matrix(uint rows, uint cols);
Matrix(const i_list & list);
Matrix(const Matrix & m);
~Matrix();

};
但我注意到,每次我尝试运行这种代码时,析构函数都会立即删除double**arr,这是存储矩阵值的地方。以下是构造函数的代码:

    Matrix::Matrix(uint rows, uint cols)
{
    mainRows = rows;
    mainCols = cols;
    arr = new double*[rows];
    for (int i = 0; i < mainRows; i++) {
        arr[i] = new double[cols];
    }
    for (int i = 0; i < mainRows; i++) {
        for (int j = 0; j < mainCols; j++) {
            arr[i][j] = 0;
        }
    }
}

Matrix::Matrix(const i_list & list)
{
    int i = 0, j = 0;
    mainRows = list.size();
    mainCols = (*list.begin()).size();
    arr = new double*[mainRows];
    for (std::initializer_list<double> I : list) {
        j = 0;
        arr[i] = new double[mainCols];
        for (double d : I) {
            arr[i][j] = d;
            j++;
        }
        i++;
    }
}

Matrix::Matrix(const Matrix & m)
{
    this->arr = m.arr;
    this->mainRows = m.mainRows;
    this->mainCols = m.mainCols;
    for (uint i = 0; i < mainRows; i++) {
        for (uint j = 0; j < mainCols; j++) {
            this->arr[i][j] = m.arr[i][j];
        }
    }
}

Matrix::~Matrix()
{
    for (uint i = 0; i < mainRows; i++) {
        delete[] arr[i];
    }
    delete[] arr; 
}
Matrix::矩阵(uint行、uint列)
{
行=行;
mainCols=cols;
arr=新的双*[行];
对于(int i=0;iarr=m.arr;
此->mainRows=m.mainRows;
此->mainCols=m.mainCols;
对于(uint i=0;iarr[i][j]=m.arr[i][j];
}
}
}
矩阵::~Matrix()
{
对于(uint i=0;i

我猜因为它两次调用同一个对象的构造函数,所以它创建了两个double**ar,这就是为什么析构函数想要删除原始的,但是我不能调用其他函数的值。有人能帮我解决我做错了什么吗?

问题是复制构造函数只复制源对象的指针,而不分配新内存

这是有问题的,因为

d = {{1,2},{3,4}};
{{1,2}、{3,4}
中创建临时对象。你的陈述实际上等于

d = Matrix({{1,2},{3,4}});
这等于

d.operator=(Matrix({{1,2},{3,4}}));
赋值完成后,两个对象指向
arr
的同一内存。然后临时对象被破坏,导致
d
内部的
arr
变得无效,因为它不再指向分配的内存


简单的解决方案很简单:为复制构造函数中指向的
arr
分配内存。更好的解决方案是停止使用指针和动态分配,而是在不需要任何复制构造函数、复制赋值运算符和析构函数的情况下使用和生存。

问题在于复制构造函数只复制源对象的指针,而不分配新内存

这是有问题的,因为

d = {{1,2},{3,4}};
{{1,2}、{3,4}
中创建临时对象。你的陈述实际上等于

d = Matrix({{1,2},{3,4}});
这等于

d.operator=(Matrix({{1,2},{3,4}}));
赋值完成后,两个对象指向
arr
的同一内存。然后临时对象被破坏,导致
d
内部的
arr
变得无效,因为它不再指向分配的内存

简单的解决方案很简单:为复制构造函数中指向的
arr
分配内存。更好的解决方案是停止使用指针和动态分配,而是在不需要任何复制构造函数、复制赋值运算符和析构函数的情况下使用和生存。

这是错误的:

Matrix::Matrix(const Matrix & m)
{
    this->arr = m.arr;
    this->mainRows = m.mainRows;
    this->mainCols = m.mainCols;
    for (uint i = 0; i < mainRows; i++) {
        for (uint j = 0; j < mainCols; j++) {
            this->arr[i][j] = m.arr[i][j];
        }
    }
}
Matrix::Matrix(常数矩阵&m)
{
这->arr=m.arr;
此->mainRows=m.mainRows;
此->mainCols=m.mainCols;
对于(uint i=0;iarr[i][j]=m.arr[i][j];
}
}
}
注意:此处不创建实际副本<代码>此->arr=m.arr
使两个指针指向内存的同一部分,因此
矩阵的新实例和旧实例共享此内存。因此,为
循环流动
没有任何作用

而当一个实例被销毁时,另一个实例指向被释放的内存

这是错误的:

Matrix::Matrix(const Matrix & m)
{
    this->arr = m.arr;
    this->mainRows = m.mainRows;
    this->mainCols = m.mainCols;
    for (uint i = 0; i < mainRows; i++) {
        for (uint j = 0; j < mainCols; j++) {
            this->arr[i][j] = m.arr[i][j];
        }
    }
}
Matrix::Matrix(常数矩阵&m)
{
这->arr=m.arr;
此->mainRows=m.mainRows;
此->mainCols=m.mainCols;
对于(uint i=0;iarr[i][j]=m.arr[i][j];
}
}
}
注意:此处不创建实际副本<代码>此->arr=m.arr
使两个指针指向内存的同一部分,因此
矩阵的新实例和旧实例共享此内存。因此,为
循环流动
没有任何作用


而当一个实例被销毁时,另一个实例指向被释放的内存

您是否过载了
运算符=
?请创建一个显示。我也建议你花点时间来学习。当然,请阅读Eric Lippert的文章,并学习如何使用调试器。如果没有,请重复。请阅读第三条规则。我没有想到这一点,谢谢大家的帮助。您是否重载了
操作符=
?请创建一个来向我们展示。我也建议你花点时间来学习。当然,请阅读Eric Lippert的文章,并学习如何使用调试器。如果你没有使用调试器,请受骗。阅读第三条规则。我没有想到这一点,谢谢大家的帮助。