删除动态分配的2D数组

23

所以我习惯于在C中进行内存管理,在那里free(pointer)将释放pointer指向的所有空间。现在,当我试图在C++中做一些简单的事情时,我自己感到困惑。

如果我有一个类似于这样分配的双精度浮点数的二维数组

double** atoms = new double*[1000];
for(int i = 0; i < 1000; i++)
  atoms[i] = new double[4];

什么是释放由new分配在堆上的内存的正确方法?

我的想法最初是这样的(因为我脑海中想到的是C语言):

for(int i = 0; i < 1000; i++)
  delete atoms[i];
delete atoms;

但是我忘记了delete[]运算符的存在,所以我相信正确的方法如下:

for(int i = 0; i < 1000; i++)
  delete[] atoms[i];
delete[] atoms;

是否理解deletedelete[]操作符之间的区别很重要?还是说我可以假设每当我使用ptr = new x[]来分配数组时,我必须使用delete[] ptr进行释放?


带有 delete [] 的版本是有效的。如果您为非数组对象调用 delete [],则会出现未定义行为。您可以在其他 SO 问题中看到:https://dev59.com/lG855IYBdhLWcg3wlVca - gomons
谢谢,我不知道为什么很难找到这样的帖子...但这基本上解决了问题。我将此标记为那个问题的重复。 - Alex
1个回答

32

实际上,一个由指针指向的指针数组仍然是一个包含内存地址的整数数据类型或数字数组。你应该对两者都使用delete[]

此外,是的,new[]隐含了delete[]

当你创建一个数组的数组时,你实际上正在创建一个包含另一个数字数组的内存地址的数字数组。无论如何,它们都是数字数组,所以都用delete[]删除。

http://coliru.stacked-crooked.com/a/8a625b672b66f6ce

#include <iostream>

int main() {

    //Hey, pointers have a finite size, no matter the indirection level!
    std::cout << "sizeof(int*): " << sizeof(int*) << std::endl;
    std::cout << "sizeof(int**): " << sizeof(int**) << std::endl;
    std::cout << "sizeof(int***): " << sizeof(int***) << std::endl;

    //Create an array of pointers that points to more arrays
    int** matrix = new int*[5];
    for (int i = 0; i < 5; ++i) {
        matrix[i] = new int[5];
        for (int j = 0; j < 5; ++j) {
            matrix[i][j] = i*5 + j;
        }
    }

    //Print out the matrix to verify we have created the matrix
    for (int j = 0; j < 5; ++j) {
        for (int i = 0; i < 5; ++i) {
            std::cout << matrix[j][i] << std::endl;
        }
    }

    //Free each sub-array
    for(int i = 0; i < 5; ++i) {
        delete[] matrix[i];   
    }
    //Free the array of pointers
    delete[] matrix;

    return 0;
}

只是为了明确,指针的类型不一定是 intlong long 或任何其他类型。标准定义了特定的类型,您可以将其强制转换为算术类型:std::intptr_tstd::uintptr_t。由于大小差异(以及可能一些非常奇怪的东西,如果您可以想象一个指针是 double 的奇怪架构),intstd::intptr_t 可能具有不同的大小(例如,32位 int 和64位 std::uintptr_t 值)。 - CinchBlue

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