【问题标题】:How do I delete dynamic non-rectangular 2-dimensional Arrays in CPP如何在 CPP 中删除动态非矩形二维数组
【发布时间】:2020-06-19 16:33:38
【问题描述】:

这是我编写的一些代码,只是为了了解如何使用指针。 这里我要分配并显示一个二维Pointerarray

int main()
{
    constexpr int size = 10;
    int** _2darray = new int* [size];

    for ( int i = 0; i < size; i++ )
    {
        *(_2darray + i) = new int[i];
        for ( int j = 0; j <= i; j++ )
        {
            *(*(_2darray + i) + j) = j;
        }
    }

    for ( int i = 0; i < size; i++ )
    {
        for ( int j = 0; j <= i; j++ )
        {
            std::cout << _2darray[i][j] << " ";
        }
        std::cout << std::endl;
    }
}

这将导致打印:

0
0 1
0 1 2
0 1 2 3
0 1 2 3 4
0 1 2 3 4 5
0 1 2 3 4 5 6
0 1 2 3 4 5 6 7
0 1 2 3 4 5 6 7 8
0 1 2 3 4 5 6 7 8 9

但如果我现在想防止内存泄漏,我想这样做:

for ( int i = 0; i < size; i++ )
  {
       delete[] _2darray[i];
  }
  delete[] _2darray;

不幸的是,这会给我一个堆损坏的异常

我猜它崩溃是因为它不知道子数组的确切大小,但我也听说 delete 总是跟踪为数组分配了多少字节。

感谢您的简短回答。

【问题讨论】:

  • 删除逻辑正确。不幸的是,在创建数组之后和删除它们之前的某个时候,程序会越界并破坏存储在数组附近的一些重要的簿记信息。找出发生这种情况的地方,您就会解决问题。
  • 当我看到一个带有&lt;= 的循环时,我总是担心。检查由for ( int j = 0; j &lt;= i; j++ ) 产生的j 的范围,以确保它是您所期望的。
  • 问题是*(_2darray + i) = new int[i];,因为 for 循环是用 i=0 初始化的。您正在分配一个包含零项的数组,然后写入它
  • int** _2darray = new int* [size]; 分配给size 指针*(_2darray + i) = new int[i]; 分配给i int 并依次将该块的起始地址分配给您的指针。当你想释放内存时,你必须首先循环你的指针释放分配的int块,然后再释放指针块。 for (int i = 0; i &lt; size; i++) delete[] _2darray[i]; 然后释放你的指针块,delete[] _2darray;。 (注意:不涉及“数组”,您已分配内存块)另请注意:_2darray[i]_2darray[i][j] 是可读的。
  • 原来 j

标签: c++ arrays pointers memory dynamic


【解决方案1】:

您的删除逻辑是正确的。

错误消息意味着您的程序正在写入超出范围的内存。比较 j &lt;= i 并不是这里的错误——我的意思是假设程序当前正在生成你想要的输出。

请注意,您希望您的第 i 个数组包含 i+1 项。特别注意第零个数组必须包含一项(即零),因此*(_2darray + i) = new int[i] 应该是*(_2darray + i) = new int[i+1]

有了这种变化,带有j &lt;= i 比较的for 循环是正确的。索引 j 将遍历包含i+1 项的第 i 个数组中的每个项。比较 j &lt; i 从零开始时只会产生 i 次迭代,因此在这种情况下您确实需要 j &lt;= i,即使这样的比较看起来不标准。考虑j &lt; i+1,它是等效的,但可能更清晰。

【讨论】:

    【解决方案2】:
    for ( int i = 0; i < size; i++ )
    {
        *(_2darray + i) = new int[i];
         //...
    }  
    

    对于第一次迭代,当i=0 你这样做时:

    *(_2darray + i) = new int[0];  
    

    这不是分配内存的好方法。看到这个C++ new int[0] — will it allocate memory?
    在你这样做之后:

    for ( int j = 0; j <= i; j++ )
    

    应该是:

    for ( int j = 0; j < i; j++ )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-10
      • 2015-08-23
      • 2021-12-30
      • 2015-06-10
      • 2012-07-04
      • 2016-08-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多