【问题标题】:c++ deallocate 2d int array error时间:2019-05-10 标签:c++deallocate 2d int array error
【发布时间】:2014-05-15 15:59:16
【问题描述】:

我在下面的代码中遇到了非常令人沮丧的错误。那是我的数组。

int **tab2 = new int*[3];

我喜欢这样分配。

for(i = 0; i < 10; i++) {
    tab2[i] = new int[3];
    tab2[i][0] = 40;
    tab2[i][1] = 10;
    tab2[i][2] = 100;
}

然后在使用它之后我想销毁它。

for(i = 0; i < 10; i++) {
    delete [] tab2[i];
}
delete [] tab2;

这每次都会导致核心转储。我尝试了许多不同的方法来破坏它,每次都得到这个错误。我在这里做错了什么?

【问题讨论】:

  • 您的代码中的一切都是错误的。目的是什么?
  • 当然,这只是说明我想要做什么的划痕。正如我所说,我想获得有关如何正确销毁它的信息。
  • 你的分配首先是错误的。
  • 我不明白为什么人们继续对好问题投反对票。虽然他犯了一些技术错误,但 SO 不仅适用于experts。 @10101101 你的问题很好。为它 +1。
  • tab2 的大小为 3,然后您将 10 个东西放入其中。

标签: c++ arrays memory-management


【解决方案1】:

这个

int **tab2 = new int*[3];

没有按照你的想法去做。

您需要一个包含十 (10) 个指针的数组,每个指针指向一个由三个整数组成的数组。

new int*[3] 是一个包含三个指针的数组。

What you want is this (live at coliru):

#include <iostream>

int main() {

  int **tab2 = new int*[10];

  for(int i = 0; i < 10; i++) {
    tab2[i] = new int[3];
    tab2[i][0] = 40;
    tab2[i][1] = 10;
    tab2[i][2] = 100;
  }

  for(int i = 0; i < 10; i++) {
    delete [] tab2[i];
  }
  delete [] tab2;

}

【讨论】:

  • @Jim :: 答案中有一个“live at coliru”链接,是的,它运行...(与new int*[3] 相比,它会通过回溯中止!:D )
  • 但我刚才还在想。当我们有这个“= new int*[10];”时,它意味着 10 行,列数不限。但是我们可以声明它,因此它将是任意数量的行,例如10 列数?从 Rook 的回答中,我知道向量支持它。但我想知道传统数组是否有可能?
  • 不,只有向量。
  • 其实,更准确地说,new int*[10]不是的意思是“10行任意列数”;它的意思是“指向 10 个指向 int 的指针的数组的第一个元素的指针”——在每个“指向 int 的十个指针”上,您随后存储了“指向 3 个 int 数组的第一个元素的指针”(但它可以是任意数量的“列”)。当您编写tab2[x][y] 时,您实际上是在说“给我tab2 的xth 元素;它是一个指向整数数组的指针;现在给我最后一个指针指向的数组的yth 元素。”知道了? :D
  • 当然 :) 但是,嘿,他们用向量做了一些魔术?如果我在这里错了,请纠正我,但我相信向量实际上是传统的数组,当涉及到它们的实现时。所以如果那是真的,那就意味着有办法,对吧? :) 如果是的话,有趣的是它有多复杂......
【解决方案2】:

int **tab2 = new int*[3];

你分配了一个大小为 3 的指针数组。但比使用

for(i = 0; i < 10; i++) {
    tab2[i] = new int[3];
    //...
}

您最多可以使用索引9 访问它。那肯定会出错。 删除过程对我来说看起来不错。要修复它,您应该分配一个大小为 10 而不是 3 的指针数组,例如

int **tab2 = new int*[10];

【讨论】:

    【解决方案3】:

    看起来您要做的是创建一个 N×M 数组,其中 N 在运行时已知,M 是固定的(在本例中为 3)。

    为什么不这样做呢?

    {
        std::array<int, 3> defaults = {{ 40, 10, 100 }};
        std::vector<std::array<int, 3>> thing(10, defaults);
    }
    

    向量 thing 在超出范围时会自动释放,并且可以在运行时设置其大小。您仍然以相同的方式访问该结构:

    thing[1][2] = 3
    

    使用标准容器和智能指针可以轻松避免手动内存管理。这样做可以让您的代码更整洁,并且减少悬空指针和内存泄漏的机会。

    【讨论】:

    • @10101101,这是正确的方法。 C++ 允许对象的确定性生命周期。看看像unique_ptr 这样的智能指针而不是原始指针。
    • @Rook,你不需要两个右括号之间的空格吗?还是他们解决了这个问题?
    • @Jim 如果您使用的 C++ 编译器足够新以理解std::array,那么它也应该足够聪明地将&gt;&gt; 作为模板声明的一部分与右移运算符区分开来。我认为它现在是标准的一部分。
    • 现在看起来它是 C++ 11 标准的一部分,但在此之前的任何编译器都不一定。
    • 对不起,我不在家。感谢您提供一些不同的解决方案,我想我将来也需要这些解决方案。再次感谢您为像我这样的菜鸟花时间。
    猜你喜欢
    • 2011-04-02
    • 1970-01-01
    • 2014-05-17
    • 2020-06-15
    • 2020-10-01
    • 2015-06-14
    • 2011-07-08
    • 2012-02-03
    • 2017-04-15
    相关资源
    最近更新 更多