让我们说我有一个功能,它所做的就是在没有任何终止的情况下调用自己。
myFunction(){
myFunction()
}
如果我运行包含此功能的程序,我最终会遇到分段错误。为什么会这样?耗尽堆栈空间?
此外,StackGuard可以防止此故障吗?为什么或为什么不呢?
答案 0 :(得分:0)
由于递归是无限的,并且对于每次调用,返回地址和基指针(帧指针)至少被压入堆栈,最终会耗尽堆栈空间,或者更常见的是,内存耗尽,如记忆是一种有限的资源。
没有什么可以防止这种情况,因为正是程序员设计了#34;这无限的递归。你会期待什么"防止这个错误"?正如我所说,这不是一个错误,因为它是程序的设计。您只是耗尽了有限的资源,导致操作系统中止程序。
<小时/> 编辑:以下是截取seg故障的示例(未经测试,基于VC2008 doc):
jmp_buf home;
void myFunction(void)
{
myFunction();
}
void SegvHandler(int signal)
{
longjmp(home);
}
int main(void)
{
signal(SIGSEGV, SegvHandler);
if (setjmp(home)) {
printf("Oops...\n)
return 1;
}
myFunction();
return 0;
}
<小时/> 测试:在VC2008中测试后,似乎无法捕获此错误。原因似乎是/可能是这样的:首先发生堆栈溢出,现在没有更多的堆栈空间来调用另一个函数,信号处理程序。
答案 1 :(得分:0)
每次调用函数时,都会在内存中为该函数调用创建一个新的堆栈帧。函数返回时,此堆栈消失。由于你的函数没有返回并继续调用新的调用,它将继续创建堆栈帧,这意味着最终你的内存不足以保留这些堆栈帧。