如果没有足够的内存来分配当前函数的堆栈(局部)变量,操作系统是否会在阈值之前向用户发送警告,然后应用程序实际上会崩溃?
发布于 2012-03-01 22:24:31
堆栈分配可能会失败,您对此无能为力。
在现代操作系统上,将为堆栈分配大量内存(目前在Linux上似乎为128k左右),并为堆栈增长保留一定范围的虚拟地址(通常要大得多,例如Linux上的8M,通常是可配置的)。如果超过了提交的部分,提交更多的内存可能会因为内存不足而失败,并且您的程序将使用SIGSEGV崩溃。如果你超过了保留的地址范围,你的程序肯定会失败,如果它覆盖了堆栈地址范围下的其他数据,可能会是灾难性的。
解决方案是不要对堆栈做疯狂的事情。即使是Linux上的初始提交空间(128k)也会比您应该使用的堆栈空间更多。不要使用调用递归,除非您对调用级别的数量有一个对数限制,不要使用巨大的自动数组或结构(包括可能由用户提供的VLA维度产生的数组或结构),这样就没问题了。
请注意,没有可移植和未来安全的方法来测量当前堆栈的使用情况和剩余的可用性,因此您只需对其保持安全即可。
编辑:关于堆栈分配,至少在现实系统中,(没有拆分堆栈)的一个保证是,你已经验证过的堆栈空间不会神奇地消失。例如,如果您成功地从b()从a()从main()调用了c(),并且它们没有使用任何大小可能不同的VLA,则在您的程序的同一实例中重复相同的调用模式不会失败。您还可以找到一些工具来对一些程序(没有使用函数指针和/或递归的程序)执行静态分析,这些工具将确定您的程序曾经消耗的最大堆栈空间量,在此之后,您可以在程序启动时进行设置,以验证您可以在继续之前成功地使用那么多空间。
https://stackoverflow.com/questions/9517724
复制相似问题