【问题标题】:C++ delete array memory without brackets still works? [duplicate]C ++删除没有括号的数组内存仍然有效吗? [复制]
【发布时间】:2013-08-05 11:25:20
【问题描述】:
int* arr = new int[count];

delete arr;

为什么会这样?我已经检查过了,它实际上释放了内存。根据我的阅读,我需要 delete[] arr; 否则它实际上不会释放所有内存。

【问题讨论】:

  • “为什么会这样?” - 它没有,它似乎在工作。
  • 没有括号,你只调用一个析构函数,而不是数组中的所有析构函数。另见stackoverflow.com/questions/2425728/…
  • 它可以工作,因为 delete 和 delete[] 对于 POD 类型具有相同的结果。在这种情况下没有内存泄漏。但是如果不是 POD 类型,程序将会崩溃(只有第一个元素会被破坏,这会导致内存泄漏)。你可以尝试使用 Valgrind 来深入了解这个问题

标签: c++ memory memory-management memory-leaks


【解决方案1】:

区别不在于分配的内存是否被正确释放——你是否使用

delete

delete[]

内存仍将被正确释放。

区别在于析构函数是否会被正确调用。

delete // will only invoke the destructor of the first element of the array.

delete[] // will invoke the destructor for *each* element of the array.

这对于像 int 或 float 这样的原始类型没有实际影响,但是当您有某个类的数组时,差异可能很关键。

【讨论】:

  • 我可以想象这样的实现。您是否有实际的实现文档证明这是真的?
  • 没有文档,只有我自己在这方面的经验是使用 Visual C++。有一段时间了,但我记得我遇到了一些错误,因为我错误地使用了 delete 而不是 delete[]。很确定它的行为与我描述的一样......请记住,*x 取消引用与 x[0] 相同的位置,并将 x 声明为指向任何关于目标对象是标量还是数组的指针,因此删除运算符除非您通过适当的删除构造告诉它,否则它不会知道它必须破坏对象数组与标量对象。
【解决方案2】:

现在尝试用每个 100 字节的字符串填充数组,看看它是否仍然释放所有分配的内存......

这是未定义的行为,并且与往常一样,有时 UB 似乎会起作用。在您的情况下,您没有内存中对象的析构函数,因此没有“进一步的工作”,只需释放所有内存 [1]。但是如果你有一个对象有一个析构函数做一些有用的事情,它(可能)不会被调用。

如果您使用new T[size]; 进行分配,您应该始终使用delete []。不要将两者混为一谈,这总是错误的——只是有时它会起作用[就像某些以英寸为单位的扳手适用于毫米螺母,反之亦然——但在公制螺母上使用英寸扳手仍然是错误的]。

[1] 请注意,这可能适用于这个特定的编译器/C++ 库组合。用不同的编译器编译它,使用不同的 C++ 库,或为不同的操作系统编译可能会导致它在你尝试相同的事情时崩溃。

【讨论】:

    【解决方案3】:

    delete 和 delete [] 实际上是不同的运算符,使用错误的总是错误的。问题是它在当时看起来通常很好,但堆已经损坏,你很可能在以后遇到明显不相关的崩溃。

    【讨论】:

    • 我不明白为什么我会因此被扣分,因为这是真的。您可以尝试运行 valgrind 或类似的内存分析工具,它会在发生堆损坏时显示。
    • 我希望反对者发表评论。我感兴趣的是哪一部分可能不正确。
    • 我不知道为什么-这是一个完全准确的答案。
    • 您不能声明“堆已损坏”。它可能不是。它是未定义的
    • @sehe:我认为整个句子的其余部分都打算被“经常”修饰。
    猜你喜欢
    • 1970-01-01
    • 2020-04-21
    • 2014-04-09
    • 2022-10-13
    • 2014-04-19
    • 2018-05-13
    • 2013-08-14
    • 2015-07-11
    • 2015-08-18
    相关资源
    最近更新 更多