C++ delete运算符混淆

3

2
像这样的问题让我想起了C++语言,它给你提供了汇编语言的强大功能,同时也具备汇编语言的易用性 :-) - Vivian River
9
http://www.parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.13 - James
2
这就是我讨厌老式数组的原因之一。如果我使用向量,我可以忽略所有这些deletedelete[]的问题。 - David Thornley
1
@Gollum:阅读那个常见问题解答链接,并继续阅读下一节(16.14)。那里解释了它的工作原理。简短回答:魔法。8v) - Fred Larson
2
@sbi:对于你建议的那个重复问题,这是一个很棒的答案。@Gollum,我建议你在怀孕之前先读一下它。;v) - Fred Larson
显示剩余5条评论
5个回答

12

看起来可能具有相同的效果,但实际并非如此。如果您的数组类型是抽象数据类型(即一个类),则最后九个元素上的析构函数不会被调用。


是的,我尝试过了,它只适用于原始类型。 - Ramadheer Singh
1
此外,如果数组的类型不是 POD 并且重新定义了 delete 和 delete[],则第一个将被调用而不是第二个,这可能会导致更令人惊讶的结果。如果全局的 delete 和 delete[] 也被重新定义,则情况相同。 - Matteo Italia
或者如果编译器本身处理单个分配和数组分配有所不同,因为它允许这样做。那么即使对于原始类型,它也不会“工作”。未定义的行为是未定义的。 - Mike Seymour

8
因为你运气好。这是未定义的行为。未定义行为的一种可能是,即使确实发生了不良事件,也似乎没有发生任何不良事件。您可能要等到以后才能发现。
您不能指望使用原始类型时是安全的。阅读此内容(由James Roth在评论中也提供链接):https://isocpp.org/wiki/faq/freestore-mgmt#delete-array-built-ins

5

不能正常工作。它仅仅表现出了正常工作的样子。展示未定义行为的代码可能在第一眼看上去就像是“正常工作”的,就像一个充满漏洞的程序在选择不当的测试套件时也可能“运行良好”。


我喜欢你的回答,你表达的方式很好,谢谢。 :) - Ramadheer Singh

1

这是未定义的行为。由于“这次可以工作”属于“未定义”的范畴,因此它可能在某些平台、某些编译器上工作。但仍然不应该这样做。你尝试过像那样dealloc一个带有析构函数的对象数组,并查看析构函数是否被调用了吗?

编辑:根据您的评论,您已经尝试过了...


0
在大多数版本的Microsoft Visual Studio中,这实际上是可以正常工作的。然而,没有理由这样做,这完全取决于您的平台。
delete[]背后的想法是,这是一种特殊情况,其中大小在编译时未知,分配框架可能希望以不同方式处理(并优化删除情况)。
严格来说,delete pointerToBaseClass也没有在编译时知道大小,但这通过虚表解决,编译器知道类在编译时是多态的。
如果您错误地处理delete[],它可能还会与替换分配器的工具(调试器、各种边界检查器等等)和用户可能使用的自定义分配器产生问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接