我不确定堆栈溢出异常是什么。当我以另一种形式调用方法时,我收到此错误。
答案 0 :(得分:7)
有时程序行为不端。程序员通过实现一些逻辑然后测试它是否正常工作来编写程序。但如果程序员在逻辑上犯了错误,就会发生不好的事情。
程序可能出错的最常见方式之一可能是无限循环。拿这个尝试添加第一个 n 整数的示例程序:
static int Sum(int n)
{
int sum = 0;
int i = 1;
while (i <= n)
sum += i;
return sum;
}
会发生什么?错误在哪里?我们忘记增加i
,因此永远不会超过n
。当你运行它时,它会运行并挂起。它永远不会自行停止。
但是如果你在一个程序中有一个无限循环而你在该循环中使用资源,那么你可能会耗尽资源。让我们采用另一个使用递归来查找总和的程序:
static int RecursiveSum(int n)
{
return n + RecursiveSum(n - 1);
}
这种方法也有问题。它也有一个“无限循环”因为我们忘了包含终止条件。我们运行它会发生什么?
由于StackOverflowException,进程终止。
在C#中,每次调用方法时,都会占用一些称为堆栈的资源。堆栈允许程序跟踪谁调用谁,以便在方法返回时,它返回到正确的位置。方法参数和局部变量也会占用堆栈空间。当方法结束并返回时,它们释放了它们使用的堆栈空间。
问题是堆栈使用内存,所以它不像时间那样是无限的资源!
因此,程序可以通过两种主要方式生成StackOverflowException
:
第一个问题由上面的第二种方法证明。但即使我们修复了这种方法来添加终止条件,虽然它适用于较小的数字,但它最终会在为足够大的 n 值生成总和之前失败。
大多数花园种类StackOverflowException
是第一种类型,但如果你不在方法中小心使用递归,你也会遇到第二个问题。
调试StackOverflowException
时,调用堆栈通常如下所示:
...
Program.RecursiveSum(int n = -7770) Line 26 + 0xf bytes C#
Program.RecursiveSum(int n = -7769) Line 26 + 0xf bytes C#
Program.RecursiveSum(int n = -7768) Line 26 + 0xf bytes C#
Program.RecursiveSum(int n = -7767) Line 26 + 0xf bytes C#
Program.RecursiveSum(int n = -7766) Line 26 + 0xf bytes C#
The maximum number of stack frames supported by Visual Studio has been exceeded.
或有时A
调用B
调用C
,然后再次调用A
等等。您只需要找到循环,设置一个断点in,a诊断正在发生的事情。
答案 1 :(得分:6)
如果你有太多的方法互相调用,就会发生stack overflow。
每当您的代码调用一个函数时,运行时都会将一个条目推送到调用堆栈,标记您在调用该函数时所处的位置。当函数完成时,运行时将ntry从堆栈中弹出并返回到那里。
当此堆栈已满时发生堆栈溢出。
答案 2 :(得分:1)
堆栈溢出是指堆空间不足时。堆栈空间通常由方法调用消耗,其中参数值被压入堆栈(当方法返回时,它们从堆栈中弹出/移除)。获得堆栈溢出的最常见情况是当您有某种递归(一种自我调用的方法)时。在每次方法调用时,你会消耗更多的堆栈空间,直到你用完为止 - 也就是当你得到堆栈溢出时。