[英]Why do I have to free 2D array twice to avoid memory leak?
I am running into a memory leak problem when allocating a 2D array.在分配二维数组时,我遇到了 memory 泄漏问题。
But I could not understand why the memory leaks.但我不明白为什么 memory 会泄漏。
My reasoning is that at Note A, I have already freed allocated memory, since data_[0] == data_
, why do I have to do the free at Note B?我的理由是,在 Note A 处,我已经释放了分配的 memory,因为data_[0] == data_
,为什么我必须在 Note B 处释放?
class Matrix {
public:
Matrix(int r, int c) {
this->rows = r;
this->cols = c;
data_ = new int*[r];
for (int i = 0; i < r; i++) {
data_[i] = new int[c];
}
}
~Matrix() {
for (int i = 0; i < this->rows; i++) {
delete [] data_[i]; // Note A;
}
delete[] data_; // Note B; <-- not doing this line will leak memory, but why?
}
private:
int rows;
int cols;
int **data_;
};
What you post there isn't really a 2D array, it's a 1D array-of-pointers ( data_
), and then you allocate a separate array-of-ints for each element of the first array (so data_[0]
is an array of c
ints, data_[1]
is an array of c
ints, and so on).您发布的内容并不是真正的二维数组,而是一维指针数组( data_
),然后为第一个数组的每个元素分配一个单独的整数数组(因此data_[0]
是c
整数数组, data_[1]
是c
整数数组,依此类推)。
Given that, it's natural that you'll have to do one delete[]
in your destructor for each new
that you performed earlier in your constructor.鉴于此,很自然,您必须在析构函数中为您之前在构造函数中执行的每个new
执行一次delete[]
。
A graphical diagram of your memory allocations and how they point to each other might look like this (if c==6
and you have set all of your arrays' integers to 0
):您的 memory 分配以及它们如何相互指向的图形图可能如下所示(如果c==6
并且您已将所有数组的整数设置为0
):
A real 2D array allocation would look like this: int * array2D = new int[6][8];
真正的二维数组分配如下所示: int * array2D = new int[6][8];
, but of course C++ only supports 2D arrays if the array-dimenions are compile-time constants, so that probably wouldn't solve the problem your Matrix
class is meant to solve. ,但当然 C++ 仅支持 2D arrays 如果数组维度是编译时常量,那么这可能无法解决您的Matrix
ZA2F2ED4F8EBC2CBB4C21A29DC40AB6D1 旨在解决的问题。
When you have created 2D array (for example 3x3), you have created 1 array with 3 elements, where each element is pointer to separate array.当您创建 2D 数组(例如 3x3)时,您创建了 1 个包含 3 个元素的数组,其中每个元素都是指向单独数组的指针。 So to clear memory for this matrix you need to clear 4 arrays (3 rows and 1 array containing pointers).因此,要清除此矩阵的 memory,您需要清除 4 arrays(3 行和 1 个包含指针的数组)。 You can check how many times in your code you are calling new operator it will be r+1 times您可以检查您在代码中调用 new 运算符的次数,它将是 r+1 次
data_ = new int*[r];// 1 time
for (int i = 0; i < r; i++ {
data_[i] = new T[c]; // r times
}
Part I: The line data_ = new int*[r];
第一部分:行data_ = new int*[r];
allocates and default initializes a dynamic array of int* through new, so you would need to provide a corresponding delete [] data_;
通过new分配并默认初始化一个int*的动态数组,因此您需要提供相应的delete [] data_;
for this line.对于这条线。
Part II: The line data_[i] = new int[c];
第二部分:行data_[i] = new int[c];
dynamically allocates and default initializes an int array and then the pointer to that first element is returned and stored as the data_[i]
element.动态分配并默认初始化一个 int 数组,然后返回指向第一个元素的指针并将其存储为data_[i]
元素。 So here again you would need a corresponding delete [] data_[i];
所以在这里你需要一个相应的delete [] data_[i];
to get rid of the memory leak.摆脱 memory 泄漏。 So these were the reasons why you need two separate delete []
.因此,这就是您需要两个单独的delete []
的原因。 The process is as shown in the screenshot.该过程如屏幕截图所示。 Also note that the important thing is the default initialization.另请注意,重要的是默认初始化。 So the int array elements will not all have a value 0 as wrongly shown in the answer by @Jeremy Friesner.因此,正如@Jeremy Friesner 在答案中错误显示的那样,int 数组元素的值不会全部为 0。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.