stackoverflow异常未处理

时间:2010-12-20 13:17:42

标签: c# winforms stack-overflow runtime-error

在下面的代码中,它应该乘以2个数字。它适用于3位数和3位数的数字但是当我给出4位数或更大的数字时,它会给出运行时错误:stackoverflow exception was unhandled。我已经评论了问题所在。我认为问题是在int中定义变量并且长时间更改它们但问题仍然存在。错误在哪里?

编辑: 现在,您是否考虑过这个问题?它没有做任何事情

        public long Prod2(long u, long v)
    {
        var numbers = textBox7.Text.Split(',').Select(p => long.Parse(p)).ToArray();
        int n = Math.Max((int)Math.Floor(Math.Log10(u) + 1),(int)Math.Floor(Math.Log10(v) + 1));        
        int threshold = 3;

        if (u == 0 || v == 0)
        {
            return 0;
        }
        else if (n <= threshold)
        {
            return u * v;
        }
        else
        {
            int m = (int)Math.Ceiling(n / 2.0);

            int x = (int)(u / Math.Pow(10, m));
            int y = (int)(u % Math.Pow(10, m));
            int w = (int)(u / Math.Pow(10, m));
            int z = (int)(v % Math.Pow(10, m));

            long r = Prod2(x + y, w + z);
            long p = Prod2(x, w);
            long q = Prod2(y, z);

            return p * (long)Math.Pow(10, 2 * m) + (r - p - q) * (long)Math.Pow(10, m) + q;
            long result = Prod2(numbers[0], numbers[1]);
            textBox1.Text = result.ToString();
        }
    }

5 个答案:

答案 0 :(得分:3)

此时你正在进入无限递归循环

 long result = bigzarb(x, w) * Math.Pow(10, m) + (bigzarb(x, w) + bigzarb(w, y)) * Math.Pow(10, m) + bigzarb(y, z);///here
    textBox1.Text = result.ToString();

我注意到这一行只在intn > 3时执行,所以也许你有一个逻辑错误?

更新:阅读完你的评论之后,我可以看到这个测试是为了说“如果这个字符串的长度是&lt; = 3那么......”实际上是这样写的实际上说“如果这个转换后的字符串的值是&lt; = 3那么......”

答案 1 :(得分:2)

简而言之,你有一个潜在的(根据输入而变化)的情况:

function bigzarb()
{
    bigzarb()
}

只要textBox7中的数字是&gt; 3,即未闭合的递归循环,它将不可避免地成为堆栈溢出。

在相关的行上放置断点,您很快就会发现问题。在不知道你的方法做什么的情况下(我不认识算法)我无法帮助清理它,但第一步可能是有条件地从函数返回一个get out子句。但是,我也看到你在使用之前覆盖了输入参数uv,所以也许你在算法中犯了错误?

答案 2 :(得分:2)

编辑:我已经完全翻译了本书中描述的算法:

public long Prod2(long u, long v)
{
    int n = Math.Max((int)Math.Floor(Math.Log10(u) + 1), (int)Math.Floor(Math.Log10(v) + 1));
    int threshold = 3;

    if(u == 0 || v == 0)
    {
        return 0;
    }
    else if(n <= threshold)
    {
        return u * v;
    }
    else
    {
        int m = (int)Math.Ceiling(n / 2.0);

        int x = (int)(u / Math.Pow(10, m));
        int y = (int)(u % Math.Pow(10, m));
        int w = (int)(u / Math.Pow(10, m));
        int z = (int)(v % Math.Pow(10, m));

        long r = Prod2(x + y, w + z);
        long p = Prod2(x, w);
        long q = Prod2(y, z);

        return p * (long)Math.Pow(10, 2 * m) + (r - p - q) * (long)Math.Pow(10, m) + q;
    }
}

要获得正确的结果,您可以通过以下其他方法调用此方法:

void Main()
{

    // Call the method and store the result in variable 'r'.
    long r = Prod2(1234, 5678);
    Console.WriteLine(r);

    /////////////////////////////////
    //
    // OR - In your case read from textBox7 and then store the result in textBox1    
    //
    /////////////////////////////////
    var numbers = textBox7.Text.Split(',').Select(p => long.Parse(p)).ToArray();
    long result = prod2(numbers[0], numbers[1]);
    textBox1.Text = result.ToString();
}

因此,在您的事件处理程序中,例如button1,您可以 this 进行调用:

public void button1_Click()
{
    var numbers = textBox7.Text.Split(',').Select(p => long.Parse(p)).ToArray();
    long result = prod2(numbers[0], numbers[1]);
    textBox1.Text = result.ToString();
}

请勿修改我拥有的Prod2,只需将其粘贴到您的代码中即可。这样,Prod2进行计算,然后您的button1_Click控制输入以及如何处理输出

答案 3 :(得分:0)

Pow方法返回double,所以我认为你的x,y,z,w和z也应该被声明为double。

答案 4 :(得分:0)

您正在为递归调用获取“StackoverFlow”。它可以更好地塑造代码中的漏洞。我建议你改变逻辑。

static int callStack = 0;

    public double bigzarb(long u, long v)
    {
        callStack++;
         ............
         ............