C++ delete array memory without brackets still works?
1 2 3
| int* arr = new int[count];
delete arr; |
为什么会这样?我已经检查过了,它实际上释放了内存。根据我读到的,我需要delete[] arr;,否则它实际上不会释放所有的内存。
- 阿法克,这是乌兰巴托。
- "为什么会这样?"-它没有,只是看起来起作用了。
- 如果没有括号,则只调用一个析构函数,而不是数组中的所有析构函数。另请参见stackoverflow.com/questions/2425728/…
- 它起作用,因为delete和delete[]对于pod类型具有相同的结果。这种情况下没有内存泄漏。但如果不是pod类型,程序将崩溃(只有第一个元素会被破坏,这会导致内存泄漏)。你可以试着用Valgrind了解这个问题。
现在尝试用每个100字节的字符串填充数组,看看它是否仍然释放所有分配的内存…
这是未定义的行为,和往常一样,有时UB似乎也会起作用。在您的情况下,内存中的对象没有析构函数,因此没有"进一步的工作",只需释放所有内存[1]。但是,如果有一个对象有一个析构函数可以做一些有用的事情,它(可能)将不会被调用。
如果使用new T[size];进行分配,则应始终使用delete []。不要把二者混用,这总是错误的-只是有时它会起作用[就像一些英寸大小的扳手在毫米螺母上起作用,反之亦然-但在公制螺母上使用英寸扳手仍然是错误的]。
(1)注意这可能适用于这个特定的编译器/C++库组合。用不同的编译器编译它,使用不同的C++库,或者编译一个不同的OS可能会导致它在尝试同样的事情时崩溃。
区别不在于分配的内存是否被正确释放——是否使用
或
内存仍将被正确释放。
区别在于是否正确调用析构函数。
2
这对int或float之类的基元类型没有实际效果,但是当您有一个类数组时,差异可能非常重要。
- 我可以想象一个实现,在这个实现中这是真的。您是否有实际的实现文档证明这是正确的?
- 没有文档,只有我自己的经验是用VisualC++编写的。有一段时间了,但我记得我遇到了错误,因为我错误地使用了删除而不是删除。很确定它的行为和我描述的一样…请记住,*x取消引用与x[0]相同的位置,并将x声明为指向与目标对象是标量对象还是数组无关的对象的指针,因此,除非您通过适当的delete构造告诉它,否则delete运算符不会知道它必须销毁对象数组与标量对象数组。
delete和delete[]实际上是不同的运算符,使用错误的运算符总是一个错误。问题是,在那个时候它通常看起来很好,但是堆已经损坏了,您很可能在以后遇到一个明显不相关的崩溃。
- 我不明白为什么我会因为这个而被贬低,因为这是真的。您可以尝试运行valgrind或类似的内存分析工具,它将在发生堆损坏时显示堆损坏。
- 我希望投反对票的人发表评论。我感兴趣的是哪一部分可能不正确。
- 我不知道为什么-这是一个完全准确的答案。
- 不能声明"堆已损坏"。可能不是。它是未定义的。
- @塞赫:我认为整个句子的其余部分都打算用"经常"来修饰。
- @戴维德利曼说的话。你基本上是说"这会发生",而实际上这是未定义的行为。这很有可能发生,但你不能肯定情况会是这样。
- 它不一定会在稍后崩溃,因为您可能不会重用堆的那部分—所以是的,它是未定义的,但它是一个您很可能稍后会涉足的地雷。