删除2D数组C ++

时间:2014-05-04 16:10:51

标签: c++ arrays pointers

这两种释放2D阵列的方法是否相似?

int** M = new int*[5];

for (int i = 0; i < 5; ++i)
    M[i] = new int[3];

for (int i = 0; i < 5; ++i) {
    for (int j = 0; j < 3; ++j) {
        M[i][j] = i + j;
    }
}

删除我:

for (int i = 0; i < 5; ++i)
    delete [] M[i];
delete [] M;

并删除II:

delete [] *M;
delete [] M;

这两个代码是否相同?

2 个答案:

答案 0 :(得分:6)

delete [] *M;delete [] M[0]相同,因此它不等同于删除循环中的所有M[i],因为只会删除第一个std::vector。循环是避免内存泄漏的正确方法。

或者更好的是,使用{{1}}代替手动分配,您不必担心删除指针。

答案 1 :(得分:5)

他们并不相似。他们不相似的一个明显原因是你打电话new[] 6次,而在delete[]的第二个版本,你打电话给“删除”2次。

delete [] *M;
delete [] M;

对于new[]的每次通话,您都应该将其与delete[]匹配,显然您没有这样做。

如果您希望这两个delete[]的呼叫匹配,则必须更改分配2d阵列的方式。改变是这样的:

int** M = new int*[5];
int *pool = new int[5*3];

for (int i = 0; i < 5; ++i, pool += 3)
    M[i] = pool;

在上面的示例中,仅对new[]进行了2次调用,一次针对行指针,另一次针对内存池。然后循环只是将池中的每个行指针指向适当的位置。

现在,“2调用”delete[]将正常工作,只要您在分配和解除分配数组之间不做任何奇怪的事情,例如损坏的内存。

以这种方式分配2d数组的优点是new[]只被调用两次,无论列数如何。因此,如果您有10,000 x 10,000矩阵,则原始版本需要调用new[] 10,001次,而使用该池的上述版本只需要调用new[] 2次。这很可能会加速程序,因为分配器只被调用两次(然后再调用两次)。

此外,如果数组数据需要是连续的,则首选上述方法,以便可以使用简单的指针算法转到任何行或列。

但是,请确保:

  • 您的阵列不会改变大小和
  • 它没有参差不齐(所有行必须具有相同的列数)。

否则维护以我描述的方式分配的矩阵变得更加困难。