这个释放内存的操作正确吗?

4

我有一个3x3的二维动态数组,如下所示:

int** matrix = new int* [3];
matrix[0] = new int [3*3];
for (int i = 1; i < 3; ++i)
    matrix[i] = matrix[i-1] + 3;

我该如何释放它?这么做正确吗:
delete [] matrix;

delete [] matrix[0];

我是否还应该删除matrix[1][2]

6个回答

8
你现在的方式,你应该:
delete [] matrix[0];
delete [] matrix;

但这是一种非常不寻常的动态二维数组分配方式。通常,您需要分配一个指针数组,然后为每一行(列)分配一个实际类型的数组。

// allocate
int **matrix = new int*[3];
for(int i = 0; i &lt 3; ++i)
  matrix[i] = new int[3];

// deallocate
for(int i = 0; i &lt 3; ++i)
  delete [] matrix[i];

delete [] matrix;

3
实际上,这是分配二维数组的常见方法。它确保矩阵中的所有数据在内存中是连续的,并且对于足够大的矩阵来说更加高效。 - eduffy
实际上,使用矩阵包装器(如@Fred Larson所指出的)比分配一个指向1D数组的指针数组更符合惯用语。 - David Rodríguez - dribeas

6

这段代码:

delete [] matrix;
delete [] matrix[0];

显然是错误的,因为您在删除矩阵后仍然使用了它。
delete [] matrix[0];
delete [] matrix;

这是正确的,但我不能保证整个代码是否有意义。

请注意不要删除matrix[1]和matrix[2],因为它们只是matrix[0]的副本。一个经验法则是你应该有与new调用相同数量的delete调用。


6
你需要为每个新的元素进行一次删除操作,按照新元素的相反顺序进行。

4
你需要阅读这篇文章:http://isocpp.org/wiki/faq/freestore-mgmt#multidim-arrays 简而言之,如果矩阵是矩形的,那么请在一个单一的块中分配它:
int* matrix = new int[3*3];

for (int i = 0; i < 3; ++i)
    for (int j = 0; j < 3; ++j)
        matrix[i*3+j] = x;

delete [] matrix;

因为它是在一个块中分配的,所以您也可以一次性删除。

或者您可以执行类似于您正在执行的操作,但是为每行进行分配。请确保先删除每行,然后再删除矩阵。

链接的文章还提供了有关将指针/数组封装在类中的信息。


你应该简要概述一下外部链接。如果链接失效,那么你的回答就会变得不太有用。 - StarPilot

1

指针数组可能是不必要的。您可以只分配9个元素的1D数组,并进行数学计算以将2D索引转换为1D索引。

除了交换delete[]操作之外,您还应该考虑当分配失败时会发生什么。如果第二次分配抛出std::bad_alloc,则您的程序将泄漏第一次分配的内存。一个正确编写的矩阵类(如Fred Larson所建议的)将为您处理内存释放。


-1

矩阵数组中的每个元素都是int[],除此之外,矩阵本身是int*(int* [])的数组,考虑到这些规则,您应该执行

delete [] matrix [i] { i = 0,1,2 }

然后执行delete [] matrix以删除矩阵本身。

希望这可以帮助您。 谢谢


“delete [] matrix[i] { i=0,1,2 }” 应该是什么意思? - bk1e
好的,我是用数学紧凑形式来编写它的,这意味着对于 i = 0、1 和 2。由于矩阵有 3 个元素,所以我没有写 for 循环,而是用这种形式来编写它。谢谢。 - mfawzymkh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接