我现在已经盯着这一段时间了,我不明白它为什么会失败。我有一个CMatrix类,实现了一个2D矩阵,如下所示:
class CMatrix {
public:
CMatrix(int height, int width);
~CMatrix();
// more stuff here
private:
void deleteData();
void allocData(int height, int width);
int rows, cols;
double** data;
};
CMatrix::CMatrix(int height, int width) {
allocData(height, width);
}
CMatrix::~CMatrix() {
deleteData();
}
它工作正常,直到我试图摧毁它。有两种方法负责分配和释放,定义如下:
void CMatrix::allocData(int height, int width) {
this->rows = height;
this->cols = width;
data = new double*[rows];
for (int i = 0; i < rows; i++) {
data[i] = new double[cols];
for (int j = 0; j < cols; j++)
data[i][j] = 0;
}
}
void CMatrix::deleteData() {
for (int i = 0; i < rows; i++) {
delete data[i];
}
delete [] data;
}
这个简单的main
代码导致它出现故障:
int main(int argc, char**
CMatrix a(2, 3);
a[0][0] = 1;
a[0][1] = 2;
a[0][2] = 3;
a[1][0] = 4;
a[1][1] = 5;
a[1][2] = 6;
return 0;
}
瓦尔德林德说:
==21005== Mismatched free() / delete / delete []
==21005== at 0x4C2A44B: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==21005== by 0x402B5C: CMatrix::deleteData() (main.cpp:375)
==21005== by 0x401731: CMatrix::~CMatrix() (main.cpp:138)
==21005== by 0x402F5D: main (main.cpp:598)
==21005== Address 0x5a06090 is 0 bytes inside a block of size 24 alloc'd
==21005== at 0x4C2AAA4: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==21005== by 0x402A84: CMatrix::allocData(int, int) (main.cpp:366)
==21005== by 0x4015FB: CMatrix::CMatrix(int, int) (main.cpp:123)
==21005== by 0x402D63: main (main.cpp:415)
在方法deleteData()
和i=0
中打印此消息。它没有说明其他i
,也没有删除[]。
我做错了什么?
答案 0 :(得分:3)
您需要在每个行上使用delete[]
,因为它们已分配new[]
:
for (int i = 0; i < rows; i++) {
delete[] data[i];
}
请注意,末尾的[i]
是数组下标,与delete[]
无关。把它想象成:
for (int i = 0; i < rows; i++) {
double* p = data[i];
delete[] p;
}
由于p
指向动态分配的数组中的第一个元素,因此它必须为delete[]
。
答案 1 :(得分:1)
除了之前确定delete[]
与delete
问题的答案外,请注意您还应定义复制构造函数和 operator=
用于CMatrix
类(或声明它们private
禁止复制语义),因为您直接管理类中的原始资源(即动态分配的内存)。
有关详细信息,请参阅Rule of Three。
或者您可以简单地使用直接资源管理器,例如std::vector
,而不是使用new[]
分配内存。您还可以定义嵌套向量以构建2D矩阵,如vector<vector<double>>
中所示。通过这种方式,std::vector
将自动执行内存分配,清理和复制。
答案 2 :(得分:1)
您的删除功能不会删除为每行中的列分配的内存块
代码应该是这样的
void CMatrix::deleteData() {
for (int i = 0; i < rows; i++) {
delete[] data[i];
}
delete [] data;
}