循环函数中的堆栈溢出错误

时间:2012-02-07 01:47:07

标签: c# stack-overflow

我是c#的新手,我正在尝试创建一个函数来检查列表中是否有某个数字,并且我想为1-10000之间的每个数字运行该函数。 目前它看起来像这样,但我得到System.StackOverflowException所以有谁知道如何正确地做到这一点?

int number = 1; 
int maxnumber = 10000; 
void LoadFavorites()
{

    if (number <= maxnumber)
    {
        if (Properties.Settings.Default.FavoriteList.Contains("'"+number+"'"))
        {
            this.listBox1.Items.Add(number);
        }
    }

    // Increases number by 1 and reruns
    number = number + 1;
    LoadFavorites(); // problem is probably here
}

8 个答案:

答案 0 :(得分:1)

你是对的。你有一个没有适当停止条件的递归函数。也许你需要一个从1到100000的循环而在那里你调用函数loadFavorites()。导致堆栈溢出是因为您无限次地调用loadFavorites(),最终会耗尽堆栈空间。

e.g。

    for(int i=number; i<maxNumber; i++)
    {
        if (Properties.Settings.Default.FavoriteList.Contains("'"+i+"'"))
            {
                this.listBox1.Items.Add(i);
            }

    }

答案 1 :(得分:1)

没有退出点,因此堆栈溢出。 您需要在递归调用上创建一个条件,否则它将永远无法退出。

示例:

    void LoadFavorites()
    {

        if (number <= maxnumber)
        {
            if (Properties.Settings.Default.FavoriteList.Contains("'"+number+"'"))
            {
                this.listBox1.Items.Add(number);
            }
        }

        // Increases number by 1 and reruns
        number = number + 1;

        if(number <= maxnumber) // create a condition to call this
          LoadFavorites(); // problem is probably here
    }

更好的方法

    void LoadFavorites()
    {

        if (number <= maxnumber)
        {
            if (Properties.Settings.Default.FavoriteList.Contains("'"+number+"'"))
            {
                this.listBox1.Items.Add(number++); // add number to list THEN increment number by one 
            }
            LoadFavorites(); 
        }

    }

答案 2 :(得分:0)

您希望将增加数量的部分移动到if语句中:

    int number = 1; 
    int maxnumber = 10000; 
    void LoadFavorites()
    {

        if (number <= maxnumber)
        {
            if (Properties.Settings.Default.FavoriteList.Contains("'"+number+"'"))
            {
                this.listBox1.Items.Add(number);
            }

            // Increases number by 1 and reruns
            number = number + 1;
            LoadFavorites(); // problem is probably here
        }
    }

答案 3 :(得分:0)

您正在递归调用LoadFavorites而没有任何规则来结束递归。只是,如果声明,请把它放在你的内心......但你为什么不这样写呢:

int number = 1; 
int maxnumber = 10000; 
void LoadFavorites()
{
    for(var i = number; i <= maxnumber; i++)
    {
        if (Properties.Settings.Default.FavoriteList.Contains("'"+number+"'"))
        {
            this.listBox1.Items.Add(number);
        }
    }
}

答案 4 :(得分:0)

问题是当数字> 100001时,您的代码仍在运行(每次递增1并且不退出循环)。 所以改变代码:

 if (number <= maxnumber)
            {
                if (Properties.Settings.Default.FavoriteList.Contains("'"+number+"'"))
                {
                    this.listBox1.Items.Add(number);
                }
                number = number + 1;
                LoadFavorites();
            }

答案 5 :(得分:0)

int number = 1; 
int maxnumber = 10000; 
void LoadFavorites()
{

    if (number <= maxnumber)
    {
        if (Properties.Settings.Default.FavoriteList.Contains("'"+number+"'"))
        {
            this.listBox1.Items.Add(number);
        }
    }

    // Increases number by 1 and reruns
    number = number + 1;
    LoadFavorites(); //**MOVE THESE:
}

更改为

int number = 1; 
int maxnumber = 10000; 
void LoadFavorites()
{

    if (number <= maxnumber)
    {
        if (Properties.Settings.Default.FavoriteList.Contains("'"+number+"'"))
        {
            this.listBox1.Items.Add(number);
            // Increases number by 1 and reruns
            number = number + 1;
            LoadFavorites(); // problem is probably here
        }
    }
}

你正在函数中调用一个函数,正如你可能知道的那样,它是递归函数。但是,使用递归,您必须具有退出条件,这会导致循环退出。

堆栈是线程中函数调用的顺序。例如,在Java中,你有main()这是你的入口点。从main()调用函数会添加到堆栈顶部。一旦堆栈达到一定大小,您的计算机就不能再缓冲更多的函数调用。它只是从堆栈中删除主函数,并且不知道返回的位置,因此它会抛出错误。 (一旦'main'被删除,它会抛出错误,而不是一旦它试图返回)。

更改的原因是您希望仅在数字为&lt; MAXNUMBER。这为递归设置了一个条件,之后函数将退出。

答案 6 :(得分:0)

您应该在循环中执行此操作,而不是使用递归。每次你递归它都会向堆栈添加信息,最终你会耗尽堆栈空间。在这种情况下,你无限地递归。 (如果数字> gt; maxnumber,你不会阻止它递归。

void LoadFavorites()
{
    int number = 1; 
    int maxnumber = 10000; 
    while (number <= maxnumber)
    {
       if (Properties.Settings.Default.FavoriteList.Contains("'"+number+"'"))
       {
           this.listBox1.Items.Add(number);
       }
       number = number + 1;
    }
}

修改:关于“'”+数字+“”已删除的其他评论

答案 7 :(得分:0)

问题在于,无论何时在c ++中调用函数,它都会占用一些内存(它需要空间来存储其变量等)​​。该内存称为堆栈帧。函数返回时会自动返回内存,但是如果你有一个递归函数,在最后的函数调用发生之前,都不能释放任何堆栈帧。在这种情况下,LoadFavorites会尝试无限调用自己,并且您的计算机不包含无限量的内存。

在C ++中,最好的答案通常是将其转换为循环 - 在这种情况下,您需要for循环。

void LoadFavorites() {
    int maxnumber = 10000;
    int number;
    for (number = 1; number <= maxnumber; number++) {
        if (Properties.Settings.Default.FavoriteList.Contains("'"+number+"'")) {
            this.listBox1.Items.Add(number);
        }
    }
}

或者,您可以将对LoadFavorites的调用移动到if语句中,这样您就不会尝试无限次地调用LoadFavorites。这可能有效,但根据您调用LoadFavorites的次数,您仍可能遇到相同的错误。使用正确的编译器优化可以避免错误,但是在这里简单地使用循环通常更安全,更清晰。