【问题标题】:Can new throws in a case of heap corruption?在堆损坏的情况下可以新抛出吗?
【发布时间】:2011-09-29 09:17:46
【问题描述】:

如果发生堆损坏,new 可以抛出吗?

如果我理解正确的话,在堆损坏的情况下,所有的赌注都没有了,任何事情都可能发生。这是正确的吗?

【问题讨论】:

  • 这是操作系统特定的问题吗?如果是,我会编辑问题
  • 如果是未定义的行为,任何事情都可能发生。它可以启动nethack。或者它可以抛出异常。不过,程序员不应该在他们的程序中依赖这种行为。最坏的情况是在你需要将它移植到另一个以不同方式实现 UB 的编译器/平台之前找不到错误。
  • FWIW,由于堆损坏,我看到了新的失败。当然,这并不意味着它总是会,但它可以。 (它实际上会做什么取决于堆的实现方式、堆的哪些部分被损坏以及如何损坏)
  • @Tony:你应该把它作为答案:)
  • @tp1:我希望看到一个启动一个专门编写的 nethack 版本的实现,这样游戏的播放方式将为未定义的行为提供定义。对于导致程序执行剩余部分的未定义行为的任​​何原因,它都是一致的,并且可以选择保留它以供将来执行程序。

标签: c++ heap-corruption


【解决方案1】:

是的,如果堆损坏,任何事情都可能发生。抛出异常是可能的,但不太可能。更有可能的是它会开始破坏内存。如果你 幸运,你只会遇到 GPF/Segmentation 错误。如果你不走运,你的程序将继续在损坏的堆上运行。

【讨论】:

    【解决方案2】:

    (根据 Als 的建议从评论移至答案,并扩展为更好或更坏 :-))

    损坏的堆会使您对该程序的任何行为期望无效。至关重要的是,抛出异常意味着一些可靠的编程处理是可能的,但没有实现检测堆损坏可能知道这是否正确,因此它们更有可能assert 或类似的。

    如果我们考虑堆可能有哪些类型的损坏:

    • 与堆当前状态相关的损坏记录。

      • 分配和/或空闲列表。损坏可能意味着稍后的堆分配取消引用无效指针,堆的某些部分被大量泄漏,在new/new[]/delete/delete[]/malloc 期间调用的后期堆分配或解除分配算法/realloc/free 无限循环等等。
      • 同步对象。堆例程的实现所使用的互斥锁状态、条件变量等可能已损坏,从而导致死锁、竞争条件以及相关函数调用期间的后续故障。
      • 记录new[] 构造的数组元素数量的计数器:损坏意味着 delete[] 将破坏错误数量的元素。如果数量减少,一些对象将不会被破坏,可能会导致它们包含的指针的内存泄漏、无法减少引用计数器、文件句柄保持打开、互斥锁保持锁定、共享内存段未销毁等。如果数量增加,delete[] 可能会访问包含数组的内存 - 可能导致 SIGSEGV - 调用相当于内存内容的reintrepet_cast<> 的析构函数作为要销毁的对象。这可能会尝试取消引用/删除/释放无效指针,关闭“随机”文件句柄等。
    • 应用数据

      • 应用程序本身通过newnew[] 创建的对象可能已损坏,从而破坏程序状态、指针和它们包含的句柄等。问题可能以多种方式表现出来。

    更一般地关于堆,充其量你可以希望当堆用完时 new 会抛出,但即使这样也远不能保证 - 特别是在new仅分配虚拟内存的操作系统上,如果以后出现页面错误不能满足他们表现为 SIGSEGV 或类似的。

    【讨论】:

    • 我的 +1 详细解释:)
    【解决方案3】:

    堆损坏是一种未定义的行为。 new 可能是 throw,也可能不是。内存分配器最终是一个读取堆内存并分配内存或提示没有可用内存的代码。现在,如果阅读窗格损坏了,事情就会变得疯狂!

    【讨论】:

      【解决方案4】:

      new 依赖于一些内存分配器,具体取决于实现。它可以是 malloc、HeapAlloc(例如),或者任何人在你碰巧使用的 operator new 上定义的任何东西。所以问题实际上是new 使用的分配器在其数据结构损坏时如何表现。当然,这取决于实现。

      【讨论】:

        猜你喜欢
        • 2014-12-11
        • 2019-07-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-03-05
        相关资源
        最近更新 更多