I am running into a memory leak problem when allocating a 2D array.
But I could not understand why the memory leaks.
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?
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).
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.
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
):
A real 2D array allocation would look like this: 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.
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. So to clear memory for this matrix you need to clear 4 arrays (3 rows and 1 array containing pointers). You can check how many times in your code you are calling new operator it will be r+1 times
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];
allocates and default initializes a dynamic array of int* through new, so you would need to provide a corresponding delete [] data_;
for this line.
Part II: The line 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. So here again you would need a corresponding delete [] data_[i];
to get rid of the memory leak. So these were the reasons why you need two separate 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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.