请定义堆栈溢出异常 - c#

时间:2011-07-17 04:04:08

标签: c# function methods compiler-errors stack-overflow

我不确定堆栈溢出异常是什么。当我以另一种形式调用方法时,我收到此错误。

3 个答案:

答案 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

  1. 无限循环的方法调用方法调用永不返回的方法
  2. 一系列过多的递归调用级别 最终会结束,但堆栈首先耗尽
  3. 第一个问题由上面的第二种方法证明。但即使我们修复了这种方法来添加终止条件,虽然它适用于较小的数字,但它最终会在为足够大的 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)

堆栈溢出是指堆空间不足时。堆栈空间通常由方法调用消耗,其中参数值被压入堆栈(当方法返回时,它们从堆栈中弹出/移除)。获得堆栈溢出的最常见情况是当您有某种递归(一种自我调用的方法)时。在每次方法调用时,你会消耗更多的堆栈空间,直到你用完为止 - 也就是当你得到堆栈溢出时。