C ++删除运算符混淆[重复]
Posted
技术标签:
【中文标题】C ++删除运算符混淆[重复]【英文标题】:C++ delete operator confusion [duplicate] 【发布时间】:2011-03-09 20:02:30 【问题描述】:可能重复:( POD )freeing memory : is delete[] equal to delete ?
char* pChar = new char[10];
delete pChar; // this should not work but it has same effect as
// delete[], WHY?
// I know this is illegal, but why does it work?
【问题讨论】:
这样的问题提醒我,C++ 是一种语言,它为您提供汇编语言的强大功能以及汇编语言的易用性:-) parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.13 这是我讨厌老式数组的原因之一。如果我使用向量,我会忽略所有这些delete
与 delete[]
的东西。
@Gollum:阅读 FAQ 链接,然后继续阅读下一节 (16.14)。这就解释了它是如何工作的。简短的回答:魔术。 8v)
@sbi:您建议的那个问题的答案很棒。 @Gollum,我建议您在怀孕前阅读那篇文章。 ;v)
【参考方案1】:
它可能看起来具有相同的效果,但事实并非如此。如果您的数组类型是抽象数据类型(即类),则不会调用最后九个元素的析构函数。
【讨论】:
是的,我试过了,它只适用于原始类型。 另外,如果数组的类型是一个非 POD 重新定义了 delete 和 delete[],第一个将被调用而不是第二个,这可能会导致更令人惊讶的结果。如果重新定义全局 delete 和 delete[] 也是如此。 或者如果编译器本身以不同方式处理单个分配和数组分配,这是允许的。那么即使使用原始类型它也不会“工作”。未定义的行为是未定义的。【参考方案2】:因为你很幸运。这是未定义的行为。未定义行为的一种可能性是似乎没有发生任何不好的事情,即使确实发生了不好的事情。你可能要等到以后才知道。
您不能指望使用原始类型是安全的。阅读此内容(也由 James Roth 在评论中链接):https://isocpp.org/wiki/faq/freestore-mgmt#delete-array-built-ins
【讨论】:
【参考方案3】:它不起作用。它只是看起来工作。表现出未定义行为的代码乍一看可能看起来“工作正常”,就像一个充满错误的程序可能在选择不当的测试套件上看起来“工作正常”一样。
【讨论】:
我喜欢你的回答,你说的方式,谢谢。 :)【参考方案4】:这是未定义的行为。并且由于“这次可以工作”属于“未定义”的类别,它可以在某些平台上,在某些编译器上工作。不过,不应该这样做。您是否尝试过使用类似的析构函数释放对象数组,并查看析构函数是否被调用?
编辑:根据您的 cmets,您确实...
【讨论】:
【参考方案5】:在大多数版本的 Microsoft Visual Studio 中,这实际上都能正常工作。但是,没有理由这样,这完全取决于您的平台。
delete[] 背后的想法是,这是一种在编译时大小未知的特殊情况,分配框架可能希望以不同方式处理(并优化删除情况)。
严格来说,delete pointerToBaseClass
在编译时也不知道大小,但这是通过虚拟表解决的,编译器在编译时知道该类是多态的。
如果您对 delete[] 处理不当,也可能会在替换分配器(调试器、各种边界检查器等)和用户可能使用的自定义分配器的工具方面出现问题。
【讨论】:
以上是关于C ++删除运算符混淆[重复]的主要内容,如果未能解决你的问题,请参考以下文章