析构函数立即调用并删除我的数组
Destructor immediately calls and deletes my arrays
我正在为一个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();
};
某些测试用例要求您定义行并使用初始值设定项列表,例如:
Matrix d(2,2);
d = {{1,2},{3,4}};
但我注意到,每次我尝试运行这种代码时,析构函数都会立即删除双 ** 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;
}
我想因为它为同一个对象调用了两次构造函数,它创建了两个双 ** 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
分配内存。更好的解决方案是停止使用指针和动态分配,而是使用 std::vector
,并遵循零规则,其中不需要任何复制构造函数、复制赋值运算符和析构函数。
这是
错误的:
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];
}
}
}
请注意,您不会在此处创建实际副本。 this->arr = m.arr;
使两个指针指向内存的同一部分,因此Matrix
的新旧实例共享此内存。因此,流动for
循环无济于事。
当其中一个实例被销毁时,另一个实例指向释放的内存。
相关文章:
- 为什么我的删除节点函数实际上没有删除节点?
- 为什么我的双向链表删除函数会删除多个节点?
- 我叫删除,但我的d-tor没有叫,为什么?
- 我可以从列表中获取对象并复制它们,但如何删除我复制的对象?
- 为什么我的程序在读取/写入文件时会删除最重要的数字?
- 将内容从第一个文件("constituencies")移动到第二个文件("temp")并在之后重命名时,我的文件被删除
- 带有AUTOMOC的CMake正在删除我的实现
- 为什么将鼠标悬停在静态 Win32 控件上会增加内存并删除我的 GUI?
- 析构函数立即调用并删除我的数组
- 如何阻止编译器删除我的功能
- 为什么我不能删除我的节点和参考
- 如何从仅使用字母的矢量字符串中删除?我的代码不会删除我需要删除的每个字符串
- vector.erase-它总是删除我的最后一个元素
- makefile删除我的.cpp文件
- 为什么 C++11 隐式删除我的默认构造函数
- 什么负责删除我的指针
- 析构函数,不会删除我的对象
- 为什么QML正在删除我的C++ListView模型
- OpenGL -鼠标左键点击不断删除我的网格
- 我如何剥离Qt库,以删除我的应用程序不使用的东西