我对何时出现堆栈溢出错误以及何时在 C 中调用无限次循环感到困惑!这两件事是否相同,如果不是,那么这两种情况之间有什么区别。请帮忙。
5 回答
对不终止的函数的递归调用肯定会导致堆栈溢出。但并不是每个堆栈溢出都是由没有基本情况的递归调用引起的。
例如,为巨大的本地数组分配存储空间也很可能导致堆栈溢出。
以下在我的机器上因分段错误而失败(由于我的分配超出了堆栈的大小,我可能尝试访问不属于我的程序的内存):
#include <stdio.h>
int main()
{
int arr[1000 * 1000 * 100];
arr[99999999] = 0;
printf("%d\n", arr[99999999]);
return 0;
}
无限循环,而您无法从中恢复的东西不会自动导致堆栈溢出(如果您简单地调用for(;;) { int i = 1; }
它本身不是堆栈溢出)。
当您的内存不足以继续计算时,堆栈溢出准确,但无限循环意味着您有循环,您的程序永远不会跳出它。
在 c 中,当循环永远不会停止时,循环被称为无限。堆栈是不同的东西。处理器使用堆栈内存来临时存储数据。请注意,所有局部变量、数组等都存储在堆栈中。当您在堆栈上存储太多变量时,它可能会超出堆栈内存的容量,此时堆栈被称为溢出。堆栈也可能由于无限循环而溢出,但并非总是如此。阅读: http ://en.wikipedia.org/wiki/Stack_overflow
当您调用另一个函数时,您正在使用堆栈——您将新函数的局部变量和返回地址放置在那里(一般来说;这取决于架构和实现)。这样做太多,你会用完堆栈,溢出它。
当您处于循环中时,您不会添加到堆栈中。
无限循环
例子:
while (1 + 1 == 2) { /* do something */ }
症状:
程序冻结或不停止运行。
解释:
条件总是为真,所以身体被一次又一次地执行......
堆栈溢出
例子:
int stackOverflow(int x)
{
if (x == 0) return 1;
return x * stackOverflow(x - 1);
}
stackOverflow(4); // returns 24
stackOverflow(-1); // crashes with "Segmentation fault (core dumped)"
症状:
程序崩溃。
解释:
调用函数时,会在称为堆栈的位置分配一些空间,用于存储局部变量、返回地址和参数等内容。当函数返回时,这个空间被释放。如果在函数完成之前调用另一个函数,则会在堆栈上为新函数分配更多内存。如果嵌套函数调用过多(通常由深度/无限递归引起),堆栈将用尽空间来存储有关所有当前调用函数的信息,并且您会遇到堆栈溢出。