Nor*_*sey 62
在现代操作系统上运行的现代语言中,当您尝试增加堆时,您将获得堆栈溢出(欢呼!)或者malloc()
或者sbrk()
或mmap()
将失败.但并非所有软件都是现代软件,所以让我们来看看故障模式:
如果堆栈增长到堆中,通常C编译器将静默地开始覆盖堆的数据结构.在现代操作系统上,将有一个或多个虚拟内存保护页面,可防止堆栈无限增长.只要保护页面中的内存量至少与增长过程的激活记录的大小一样大,操作系统就会保证您出现段错误.如果你在没有MMU的机器上运行DOS,你可能已经被软管了.
如果堆增长到堆栈中,操作系统应始终了解情况,某种系统调用将失败.执行malloc()
几乎肯定会注意到失败和回报NULL
.之后会发生什么事取决于你.
我总是对编译器编写者希望操作系统将防护页面放在适当位置以防止堆栈溢出的意愿感到惊讶.当然,这个技巧很有效,直到你开始拥有数千个线程,每个线程都有自己的堆栈......
Jim*_*nis 42
这将取决于平台.在许多平台上它实际上根本不可能发生(堆和堆栈分配在不同的页面中,而且两个都应该满足.
请记住,堆向上增长和堆栈向下增长的想法只是概念性的.在非常小的系统(如运行CP/M的旧8位微处理器)和某些PIC和其他平板存储器模型系统(没有MMU或任何其他虚拟或受保护的内存支持)上,堆和堆栈可能实际上是以这种方式实现.在这种情况下,行为将是未定义的......但是一旦代码试图返回到损坏的堆栈顶部的某个地址或者从堆的一个部分到另一个部分或者间接指针,它几乎肯定会崩溃. ..
无论如何,您不会在任何现代通用工作站或服务器上看到它.您将达到资源限制并获得malloc故障,否则您将遇到虚拟内存,最终系统会自动陷入"点击红色开关"的颤抖状态.
Pau*_*xon 12
在那些时候,是时候转向Egon Spengler博士的圣人话语了....
如果幸运的话,会出现内存不足或堆栈异常.如果你运气不好,程序将进入无效内存并引发错误的内存异常.如果你非常不走运,那么程序会继续进行,并且会破坏它不应该的东西,你永远不知道为什么你的程序失败了.
最后当然宇宙可能会破裂.
归档时间: |
|
查看次数: |
14566 次 |
最近记录: |