为什么析构函数不释放数组内存?
Why destructor doesn't free array memory?
我的问题是为什么析构函数不释放我的临时数组的内存? Valgrind 告诉我,我在构造函数中使用了 new 运算符,但之后没有删除内存。当我简单地写 delete temp
时,我在 Valgrind 中遇到了很多错误,例如 Invalid read of size、double free 等。你们能告诉我这里发生了什么吗?
array_xyz(const int r, const int c, double **arg_array) {
rows = r;
cols = c;
array_xyz *temp = new array_xyz();
temp->arr = new double *[rows];
temp->rows = r;
temp->cols = c;
arr = new double *[rows];
for (int i = 0; i < rows; i++) {
arr[i] = new double [cols];
temp->arr[i] = new double [cols];
}
for (int j = 0; j < rows; j++) {
for (int k = 0; k < cols; k++)
temp->arr[j][k] = arg_array[j][k];
}
arr = temp->arr;
//delete temp; -> doesn't work, valgrind tells that I free memory twice
}
array_xyz() {
rows = 0;
cols = 0;
arr = NULL;
}
~array_xyz() {
for (int i = 0; i < rows; i++)
delete []arr[i];
delete []arr;
}
谢谢,我知道了。我想将值从 arg_array 复制到 arr,好的一点是那里甚至不需要 temp。
解决方法如下:
array_xyz(const int r, const int c, double **arg_array) {
rows = r;
cols = c;
arr = new double *[rows];
for (int i = 0; i < rows; i++) {
arr[i] = new double [cols];
}
for (int j = 0; j < rows; j++) {
for (int k = 0; k < cols; k++)
arr[j][k] = arg_array[j][k];
}
}
您分配了 arr
(及其所有行)和 temp_arr
(及其所有行)。然后你做arr=temp_arr;
。它不会将 temp_arr
的值复制到 arr
。相反,它强制 arr
指向与 temp_arr
相同的地址。之前分配给 arr
的整个内存现在是孤立的(没有指向它的指针,所以你不能释放它,它没有任何用处)。如果您删除 temp_arr
,它会自动删除 arr
,因为它们现在指向内存中的同一个位置。
这条语句之后
arr = temp->arr;
两个指针 arr
和 temp->arr
指向相同的内存扩展。
如果你添加这个satetment
delete temp
然后 class array_xyz
的析构函数释放此内存范围(以及动态分配数组的元素指向的范围)。此外,所创建对象的析构函数也将删除相同的内存范围,因为它自己的指针 arr
指向相同的内存。因此,将尝试两次释放相同的内存范围。
不清楚您为什么要使用由指针 temp
指向的动态创建的中间对象。完全是多余的代码,只会让构造函数的读者感到困惑。
我的问题是为什么析构函数不释放我的临时数组的内存? Valgrind 告诉我,我在构造函数中使用了 new 运算符,但之后没有删除内存。当我简单地写 delete temp
时,我在 Valgrind 中遇到了很多错误,例如 Invalid read of size、double free 等。你们能告诉我这里发生了什么吗?
array_xyz(const int r, const int c, double **arg_array) {
rows = r;
cols = c;
array_xyz *temp = new array_xyz();
temp->arr = new double *[rows];
temp->rows = r;
temp->cols = c;
arr = new double *[rows];
for (int i = 0; i < rows; i++) {
arr[i] = new double [cols];
temp->arr[i] = new double [cols];
}
for (int j = 0; j < rows; j++) {
for (int k = 0; k < cols; k++)
temp->arr[j][k] = arg_array[j][k];
}
arr = temp->arr;
//delete temp; -> doesn't work, valgrind tells that I free memory twice
}
array_xyz() {
rows = 0;
cols = 0;
arr = NULL;
}
~array_xyz() {
for (int i = 0; i < rows; i++)
delete []arr[i];
delete []arr;
}
谢谢,我知道了。我想将值从 arg_array 复制到 arr,好的一点是那里甚至不需要 temp。
解决方法如下:
array_xyz(const int r, const int c, double **arg_array) {
rows = r;
cols = c;
arr = new double *[rows];
for (int i = 0; i < rows; i++) {
arr[i] = new double [cols];
}
for (int j = 0; j < rows; j++) {
for (int k = 0; k < cols; k++)
arr[j][k] = arg_array[j][k];
}
}
您分配了 arr
(及其所有行)和 temp_arr
(及其所有行)。然后你做arr=temp_arr;
。它不会将 temp_arr
的值复制到 arr
。相反,它强制 arr
指向与 temp_arr
相同的地址。之前分配给 arr
的整个内存现在是孤立的(没有指向它的指针,所以你不能释放它,它没有任何用处)。如果您删除 temp_arr
,它会自动删除 arr
,因为它们现在指向内存中的同一个位置。
这条语句之后
arr = temp->arr;
两个指针 arr
和 temp->arr
指向相同的内存扩展。
如果你添加这个satetment
delete temp
然后 class array_xyz
的析构函数释放此内存范围(以及动态分配数组的元素指向的范围)。此外,所创建对象的析构函数也将删除相同的内存范围,因为它自己的指针 arr
指向相同的内存。因此,将尝试两次释放相同的内存范围。
不清楚您为什么要使用由指针 temp
指向的动态创建的中间对象。完全是多余的代码,只会让构造函数的读者感到困惑。