简体   繁体   English

为什么我必须释放 2D 数组两次以避免 memory 泄漏?

[英]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。 截图1

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM