【问题标题】:how to avoid or handle stack overflow exception in C#?如何避免或处理 C# 中的堆栈溢出异常?
【发布时间】:2014-07-20 01:20:30
【问题描述】:

如何避免或处理这段代码中的堆栈溢出异常?
(C#语言)

    public void expand(int i, int j)
    {
        int dan = danger(i, j);
        if (dan == 0)
        {
            button_show(i, j, "");
            if (i != 0)
                expand(i - 1, j);
            if (i != 7)
                expand(i + 1, j);
            if (j != 0)
                expand(i, j - 1);
            if (j != 7)
                expand(i, j + 1);
        }
        else if (dan > 0 && dan < 9)
        {
            button_show(i, j, dan.ToString());
        }


    }

这个方法发生异常

    public void button_show(int i, int j, string danger)
    {
            this.Controls["b" + i + "n" + j].Text = danger;//this line throw an stack overflow exception
            this.Controls["b" + i + "n" + j].Enabled = false;
    }

危险方法是这样的

public int danger(int i, int j)
    {
        //Check if button is mine
        if (first.mines[i][j] == true)
            //9 is mine
            return 9;
        else
        {
            //d measures danger
            int d = 0;
            if (i != 0 && j != 0)
            {
                if (first.mines[i - 1][j - 1] == true) //top-left
                    d++;
            }
            if (j != 0)
            {
                if (first.mines[i][j - 1] == true) //top
                    d++;
            }
            if (i != 7 && j != 0)
            {
                if (first.mines[i + 1][j - 1] == true) //top-right
                    d++;
            }
            if (i != 0)
            {
                if (first.mines[i - 1][j] == true) //left
                    d++;
            }
            if (i != 7)
            {
                if (first.mines[i + 1][j] == true) //right
                    d++;
            }
            if (i != 0 && j != 7)
            {
                if (first.mines[i - 1][j + 1] == true) //bottom-left
                    d++;
            }
            if (j != 7)
            {
                if (first.mines[i][j + 1] == true) //bottom
                    d++;
            }
            if (i != 7 && j != 7)
            {
                if (first.mines[i + 1][j + 1] == true) //bottom-right
                    d++;
            }
            return d;

        }
    }

此方法第一次调用expand方法

    public void check(int i, int j)
    {
        int dan = danger(i, j);
        if (dan == 9)
            mine();
        else if (dan > 0 && dan < 9)
            button_show(i, j, dan.ToString());
        else if (dan == 0)
            expand(i, j);
    }

Visual Studio 显示了这个关于异常的文本,没有更多详细信息

An unhandled exception of type 'System.StackOverflowException' occurred in mscorlib.dll

【问题讨论】:

  • 请显示完整的异常堆栈
  • 你的danger 方法是什么样的?
  • 您需要一个退出条件。在您当前的实现中,您从button_show 调用expand,无论dan==0 与否,您立即调用button_show,再次调用expand,(无限重复)。您需要确保该循环被打破的地方
  • 但是当危险不是0时,回路必须刹车

标签: c# exception stack overflow


【解决方案1】:

您正在使用递归,递归需要一个结束条件来停止递归。如果没有,您将触发 stackoverflow 异常。检查您的结束条件是否在您正在测试的情况下有效。您可以在非递归函数中处理所有隐含函数,但是我猜您只是缺少结束/退出条件。

你必须考虑到你已经知道的地方。此时,您正在一遍又一遍地重新检查它们。

【讨论】:

  • 但在扩展方法中,当 'dan' 变量不为零时,必须停止递归
  • 是的,如果两个 0 字段彼此相邻,第一个字段检查第二个字段,第二个字段检查第一个字段,它会一遍又一遍地重复
猜你喜欢
  • 2012-08-22
  • 1970-01-01
  • 2013-10-29
  • 2020-03-08
  • 1970-01-01
  • 2010-11-30
  • 2010-12-04
  • 1970-01-01
相关资源
最近更新 更多