【问题标题】:Deleting a dynamically allocated 2D array [duplicate]删除动态分配的二维数组
【发布时间】:2015-08-23 14:17:17
【问题描述】:

所以我习惯了 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 [],它就是一个ub。您可以在其他 SO 问题中看到:stackoverflow.com/questions/4255598/delete-vs-delete
  • 谢谢,由于某种原因,我很难找到这样的帖子......但这几乎可以解决问题。我将此标记为该问题的重复项

标签: c++ memory-management delete-operator


【解决方案1】:

实际上,指针指向的指针数组仍然是整数数据类型或数字的数组,用于保存内存地址。您应该同时使用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 值)。
猜你喜欢
  • 2015-06-10
  • 1970-01-01
  • 1970-01-01
  • 2013-11-24
  • 1970-01-01
  • 2021-02-03
  • 2015-02-10
  • 2018-07-10
相关资源
最近更新 更多