简体   繁体   English

递归函数导致堆栈溢出

[英]Function with recursion is causing stack overflow

I am having a problem with my function made to find a path in a maze of 1s and 0s, return true if it is on that path or has found the exit, and return false if the maze is unsolvable.我的函数有问题,用于在 1 和 0 的迷宫中找到路径,如果它在该路径上或找到出口,则返回 true,如果迷宫无法解决,则返回 false。 I am getting a stack overflow error any time I try checking for the "- 1s" of my variables but my base cases should be preventing that.每当我尝试检查变量的“-1s”时,我都会收到堆栈溢出错误,但我的基本情况应该可以防止这种情况发生。 Is there a way to use less stack space with recursion?有没有办法通过递归使用更少的堆栈空间? Here is my code这是我的代码

bool Pathfinder::check(string& maze, stack<string>& path, int x, int y, int z) 
{int checking = 0;
    if ((x == 4) && (y == 4) && (z == 4))
    {
        path.push(this->createCoords(x, y, z));
        return true;
    }
    else
    {
        if ((x + 1) < 1 || (x + 1) > columns)
        {
            return false;
        }
        if ((y + 1) < 1 || (y + 1) > rows)
        {
            return false;
        }
        if ((z + 1) < 1 || (z + 1) > floors)
        {
            return false;
        }
        if ((x < 0) || (y < 0) || (z < 0))
        {
            return false;
        }
        if (this->getValue(maze, x, y, z) == 1)
        {
            this->setValue(maze, x, y, z, 2);
        }
        else
        {
            return false;
        }
    }


    if (this->check(maze, path, x + 1, y, z) ||
        this->check(maze, path, x, y + 1, z) ||
        this->check(maze, path, x, y, z + 1))
    {
        checking++;
    }
    if (this->check(maze, path, x - 1, y, z) && checking == 1) //Overflow error comes from here
    {
        checking++;
    }
    if (this->check(maze, path, x, y - 1, z) && checking == 2)
    {
        checking++;
    }
    if (this->check(maze, path, x, y, z - 1) && checking == 3)
    {
        path.push(this->createCoords(x, y, z));

        return true;
    }

    return false;
}

You cannot use "less stack space" for the simple reason that when the amount of required stack space is infinite, anything less than infinite is still infinite.你不能使用“更少的堆栈空间”,原因很简单,当所需的堆栈空间是无限的时,任何小于无限的东西仍然是无限的。 That's what infinity means.这就是无穷大的意思。 The shown algorithm is logically flawed, and clearly results in infinite recursion.所示算法在逻辑上有缺陷,显然会导致无限递归。 Let's label some of these recursive calls as follows:让我们将其中一些递归调用标记如下:

if (this->check(maze, path, x + 1, y, z) ||   // A
    this->check(maze, path, x, y + 1, z) ||   // B
    this->check(maze, path, x, y, z + 1))     // C
{
    checking++;
}

if (this->check(maze, path, x - 1, y, z) && checking == 1) // D
{
    checking++;
}

The initial value of checking is 0. We can draw the following conclusions based on the above code. checking的初始值为0,根据上面的代码我们可以得出以下结论。

1) Recursive call A always takes place. 1) 递归调用A总是发生。

2) there's some set of coordinates for which either A, or B, or C recursive cals returns true 2) 有一些坐标集,A、B 或 C 递归校准返回true

3) And when condition 2) holds true, recursive call D always takes place. 3) 当条件 2) 成立时,递归调用D总是发生。

Therefore, whenever condition "2)" is true, this guarantees infinite recursion.因此,只要条件“2)”为真,就保证了无限递归。 Recursive call A which then makes recursive call D is logically infinite recursion.递归调用 A 然后进行递归调用 D 在逻辑上是无限递归。

This is because prior to the recursive call that results in condition 2) being true, recursive call A passes x+1 .这是因为在导致条件2)为真的递归调用之前,递归调用A通过x+1 And inside the recursive call condition "2)" evaluates to true, which results in recursive call D.并且在递归调用条件“2)”中评估为真,这导致递归调用 D。

But this results in two consecutive nested recursive calls, first passing x+1 , then x+1-1 on the second one, with the same y and z values.但这会导致两个连续的嵌套递归调用,首先传递x+1 ,然后在第二个传递x+1-1 ,具有相同的yz值。 The second recursive call then passes the same values for x , y , and z as its grandparent call, and there's nothing here that will stop this infinite recursion.然后第二个递归调用传递与它的祖父调用相同的xyz值,这里没有任何东西可以阻止这种无限递归。

The shown algorithm is fundamentally broken.所示的算法从根本上被破坏了。 You will need to figure out why it's broken, and what should be the correct algorithm.你需要弄清楚它为什么坏了,什么应该是正确的算法。 This cannot be answered based on the limited information in the question, the only thing that can be trivially determined is the reason, and the explanation why infinite recursion occurs;这不能根据问题中的有限信息来回答,唯一可以确定的是原因,以及无限递归发生的解释; it's rather obvious.这是相当明显的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM