如果堆损坏,可以new
抛出吗?
如果我理解正确,在堆损坏的情况下,所有赌注都会关闭,任何事情都可能发生。这是对的吗?
答案 0 :(得分:8)
是的,如果堆已损坏,任何事情都可能发生。抛出异常是可能的,但不太可能。更有可能的是,它会开始摧毁记忆;如果你幸运,你只会得到一个GPF / Segmentation故障。如果你运气不好,你的程序将继续以损坏的堆运行。
答案 1 :(得分:6)
(从评论转移到Als建议的答案,并延伸到更好或更差:-))
损坏的堆会使您对程序的任何行为期望无效。至关重要的是,抛出异常意味着一些可靠的程序化处理是可能的,但没有实现检测堆损坏可能知道这是否真实,因此它们更可能assert
或类似
如果我们考虑堆可能具有哪些类型的损坏:
与堆的当前状态相关的损坏记录。
new
/ new[]
/ delete
/ {期间调用的堆分配或解除分配算法{1}} / delete[]
/ malloc
/ realloc
无限循环等等。free
构造的数组元素的数量:腐败意味着delete []将破坏错误数量的元素。如果数量减少,一些对象将不会被破坏,可能导致它们包含指针的内存泄漏,未能减少参考计数器,文件句柄保持打开,互斥锁保持锁定,共享内存段未被破坏等。如果数量增加,new[]
可能访问包含数组的内存 - 可能导致SIGSEGV - 调用与内存内容delete[]
相当的析构函数作为要销毁的对象。这可能会尝试取消引用/删除/释放无效指针,关闭“随机”文件句柄等。申请数据
reintrepet_cast<>
和new
创建的对象可能已损坏,破坏程序状态,指针和包含它们的句柄等。问题可能以多种方式表现出来。更一般地说关于堆,最好你可以希望新的将在堆耗尽时抛出,但即使这远远没有保证 - 特别是在只有new[]
分配虚拟内存的操作系统上,以及如果以后不能满足页面错误,它们表现为SIGSEGV或类似的。
答案 2 :(得分:5)
堆损坏是一种未定义的行为。 new
throw
可能不是{{1}}。内存分配器最终是一个代码,它读取堆内存并分配内存或提示没有可用的内存。现在,如果阅读窗格已损坏,那么事情就会变得疯狂!
答案 3 :(得分:3)
new
依赖于某些内存分配器,具体取决于实现。它可以是malloc,HeapAlloc(例如),或者您在碰巧使用的操作符上定义的任何内容。所以问题实际上是new
使用的分配器在其数据结构被破坏时的行为方式。当然,这取决于实现。