删除动态数组的正确方法是什么?

What is the proper way to delete a dynamic array?

本文关键字:方法 是什么 动态 数组 删除      更新时间:2023-10-16

我动态创建了一个3D数组t (tint***类型)。现在我正试图删除它。

我遇到了两个建议:一种是简单地执行

delete[] t;

显然,它会删除所有内容

另一种是像

for(int i=0;i<3;i++)
{
    for(int j=0;j<t1[i];j++)
    {
        delete[] t[i][j];//delete all 1D array
    }
    delete[] t[i];//delete all 2D array
}
delete[] t;//delete the 3D array

(t1存储t[i]的大小,t2存储t[i][j]的大小)

最好的方法是什么?

正如@aschepler在评论中提到的,这取决于内存最初是如何分配的。我假设您可能是这样分配内存的:

int*** t = new int**[dim1];
for (int i = 0; i < dim1; i++) {
   t[i] = new int*[dim2];
   for (int j = 0; j < dim2; j++) {
      t[i][j] = new int[dim3];
   }
}

如果您以这种方式分配内存,那么内存看起来像这样:

                      [ 0 ] --> [ 0 ][ 1 ][ 2 ][ 3 ]
                +---> [ 1 ] --> [ 0 ][ 1 ][ 2 ][ 3 ]
                |     [ 2 ] --> [ 0 ][ 1 ][ 2 ][ 3 ]
                |
 t ---> [ 0 ] [ 1 ]
          |
          |     [ 0 ] --> [ 0 ][ 1 ][ 2 ][ 3 ]
          +---> [ 1 ] --> [ 0 ][ 1 ][ 2 ][ 3 ]
                [ 2 ] --> [ 0 ][ 1 ][ 2 ][ 3 ]

现在,假设你只写

delete[] t;

如果你这样做,那么内存将看起来像这样:

                      [ 0 ] --> [ 0 ][ 1 ][ 2 ][ 3 ]
                      [ 1 ] --> [ 0 ][ 1 ][ 2 ][ 3 ]
                      [ 2 ] --> [ 0 ][ 1 ][ 2 ][ 3 ]
 t ---> xxx
                [ 0 ] --> [ 0 ][ 1 ][ 2 ][ 3 ]
                [ 1 ] --> [ 0 ][ 1 ][ 2 ][ 3 ]
                [ 2 ] --> [ 0 ][ 1 ][ 2 ][ 3 ]

换句话说,您回收了一个数组,但泄漏了大部分内存。哦!

另一方面,如果您使用for循环版本的删除代码,您最终会回收所有内存,因为您已经遍历了所有指针并释放了分配的每个数组。

一般来说,每个分配都应该有一个匹配的释放,所以如果您多次调用new[],则需要调用delete[]相同次数。

正如一些评论所指出的那样,可能有比使用int ***更好的方法来管理3D数组。c++中的一般趋势是使用对象尽可能多地自动管理内存。考虑一下Boost multi_array类型,或者考虑编写一个围绕std::vector的包装器,以行为主的顺序存储条目。

正确分配内存和正确分配内存一样重要。在堆上创建多暗淡数组时,我们应该像删除它一样小心:

#include <iostream>
using std::cout;
using std::endl;
int main()
{
    int*** ptrInt = new int**[3];
    for(int i(0); i < 3; i++)
        ptrInt[i] = new int*[3];
    for(int i = 0; i < 3; i++)
    {
        for(int j(0); j < 3; j++)
            ptrInt[i][j] = new int[3];
    }

    for(int i = 0; i < 3; i++)
    {
        for(int j(0); j < 3; j++)
            for(int k(0); k < 3; k++)
                ptrInt[i][j][k] = k;
    }
    for(int i = 0; i < 3; i++)
    {
        for(int j(0); j < 3; j++)
            for(int k(0); k < 3; k++)
                cout << "ptrInt[" << i << "][" << j << "][" << k << "]: " << ptrInt[i][j][k] << endl;
    }
    // now freeing memory:
    for(int i = 0; i < 3; i++)
    {
        for(int j(0); j < 3; j++)
            delete[] ptrInt[i][j];
        delete[] ptrInt[i];
    }
    delete[] ptrInt;
    ptrInt = NULL; // if we call delete again on a null pointer it's ok

    cout << endl;
    return 0;
}