【问题标题】:Please define a stack overflow exception -- c#请定义一个堆栈溢出异常——c#
【发布时间】:2011-10-07 00:03:07
【问题描述】:

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

【问题讨论】:

  • 如果您发布一些代码会更好 - 这样我们就可以做我们真正在这里的目的:帮助您修复您的异常,而不是定义易于搜索的术语。

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


【解决方案1】:

有时程序行为不端。程序员通过实现一些逻辑然后测试它是否正常工作来编写他们的程序。但是如果程序员在逻辑上犯了错误,就会发生不好的事情。

程序出错的最常见方式之一可能是无限循环。以这个尝试将前 n 个整数相加的示例程序为例:

static int Sum(int n)
{
    int sum = 0;
    int i = 1;
    while (i <= n)
        sum += i;
    return sum;
}

会发生什么?错误在哪里?我们忘记增加i,所以它永远不会超过n。当您运行它时,它会运行并挂起。它永远不会自行停止。

但是,如果您的程序中有一个无限循环,并且在该循环中使用 resources,则可能会耗尽资源。让我们来看另一个使用递归求和的程序:

static int RecursiveSum(int n)
{
    return n + RecursiveSum(n - 1);
}

这个方法也有问题。它也有一个“无限循环”,因为我们忘记包含终止条件。当我们运行它时会发生什么?

由于 StackOverflowException 而终止进程。

在 C# 中,每次调用一个方法时,都会消耗一些称为堆栈的资源。堆栈允许程序跟踪谁调用了谁,以便当方法返回时,它会返回到正确的位置。方法参数和局部变量也会占用堆栈空间。当方法结束并返回时,它们会释放它们使用的堆栈空间。

问题是堆栈使用内存,所以它不像时间一样是无限资源!

因此,程序可以通过两种主要方式生成StackOverflowException

  1. 无限循环的方法调用方法调用永远不会返回的方法
  2. 一系列太多递归调用级别,最终结束,但堆栈首先用完

第一个问题由上面的第二种方法演示。但即使我们修复该方法以添加终止条件,虽然它适用于较小的数字,但它最终会在生成足够大的 n 值的总和之前失败。

大多数花园品种StackOverflowExceptions 属于第一种类型,但如果您在方法中不仔细使用递归,您也会遇到第二个问题。

在调试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 等等。你只需要找到循环,设置断点,诊断发生了什么。

【讨论】:

  • 当然,如果 C# 有一个发出尾调用的编译器,它可能不会在这个例子中使用 stackoverflow ;p
  • 哇...这真的很有帮助!谢谢!
【解决方案2】:

stack overflow 发生在您有太多方法相互调用时。

每当您的代码调用一个函数时,运行时都会将一个条目推送到一个调用堆栈,以标记您在调用该函数时所处的位置。当函数完成时,运行时将 ntry 从堆栈中弹出并返回到那里。

堆栈满时发生堆栈溢出。

【讨论】:

    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-27
      • 2010-12-08
      • 2020-11-14
      相关资源
      最近更新 更多