【问题标题】:C++ delete operator confusion [duplicate]C ++删除运算符混淆[重复]
【发布时间】: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++ 是一种语言,它为您提供汇编语言的强大功能以及汇编语言的易用性:-)
  • 这是我讨厌老式数组的原因之一。如果我使用向量,我会忽略所有这些 deletedelete[] 的东西。
  • @Gollum:阅读 FAQ 链接,然后继续阅读下一节 (16.14)。这就解释了它是如何工作的。简短的回答:魔术。 8v)
  • @sbi:您建议的那个问题的答案很棒。 @Gollum,我建议您在怀孕前阅读那篇文章。 ;v)

标签: c++ delete-operator


【解决方案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[] 处理不当,也可能会在替换分配器(调试器、各种边界检查器等)和用户可能使用的自定义分配器的工具方面出现问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-07-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-06
        • 1970-01-01
        • 2014-02-08
        • 1970-01-01
        相关资源
        最近更新 更多