Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 具有递归的函数导致堆栈溢出_C++_Recursion - Fatal编程技术网

C++ 具有递归的函数导致堆栈溢出

C++ 具有递归的函数导致堆栈溢出,c++,recursion,C++,Recursion,我的函数在1和0的迷宫中查找路径时遇到问题,如果路径在该路径上或已找到出口,则返回true,如果迷宫无法解决,则返回false。每当我尝试检查变量的“-1”时,就会出现堆栈溢出错误,但我的基本情况应该可以防止这种情况发生。有没有一种方法可以在递归中使用更少的堆栈空间?这是我的密码 bool Pathfinder::check(string& maze, stack<string>& path, int x, int y, int z) {int checking =

我的函数在1和0的迷宫中查找路径时遇到问题,如果路径在该路径上或已找到出口,则返回true,如果迷宫无法解决,则返回false。每当我尝试检查变量的“-1”时,就会出现堆栈溢出错误,但我的基本情况应该可以防止这种情况发生。有没有一种方法可以在递归中使用更少的堆栈空间?这是我的密码

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;
}
bool Pathfinder::检查(字符串和迷宫、堆栈和路径、int x、int y、int z)
{int检查=0;
如果((x==4)和&(y==4)和&(z==4))
{
push(this->createCoords(x,y,z));
返回true;
}
其他的
{
如果((x+1)<1 | |(x+1)>列)
{
返回false;
}
如果((y+1)<1 | |(y+1)>行)
{
返回false;
}
如果((z+1)<1 | |(z+1)>楼层)
{
返回false;
}
如果((x<0)| |(y<0)| |(z<0))
{
返回false;
}
如果(此->获取值(迷宫,x,y,z)==1)
{
该->设置值(迷宫,x,y,z,2);
}
其他的
{
返回false;
}
}
如果(此->检查(迷宫、路径、x+1、y、z)||
此->检查(迷宫、路径、x、y+1、z)||
此->检查(迷宫、路径、x、y、z+1))
{
检查++;
}
如果(this->check(迷宫,路径,x-1,y,z)&&checking==1)//溢出错误来自这里
{
检查++;
}
如果(这个->检查(迷宫,路径,x,y-1,z)&&checking==2)
{
检查++;
}
如果(这个->检查(迷宫,路径,x,y,z-1)&&checking==3)
{
push(this->createCoords(x,y,z));
返回true;
}
返回false;
}
您不能使用“更少的堆栈空间”,原因很简单,当所需的堆栈空间量为无穷大时,小于无穷大的任何内容仍然是无限的。这就是无限的意思。所示的算法在逻辑上有缺陷,显然会导致无限递归。让我们对其中一些递归调用进行如下标记:

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++;
}
检查的初始值为0。基于以上代码,我们可以得出以下结论

1) 递归调用
A
总是发生

2) 有一组坐标,A、B或C递归CAL返回
true

3) 当条件2)成立时,递归调用
D
总是发生

因此,只要条件“2”为真,这就保证了无限递归。然后进行递归调用D的递归调用A在逻辑上是无限递归

这是因为在导致条件
2)
为真的递归调用之前,递归调用
A
通过
x+1
。在递归调用条件“2”中,计算结果为true,这将导致递归调用D

但这会导致两个连续的嵌套递归调用,首先传递
x+1
,然后在第二个上传递
x+1-1
,具有相同的
y
z
值。然后,第二个递归调用为
x
y
z
传递与其祖辈调用相同的值,这里没有任何东西可以阻止这种无限递归


显示的算法从根本上被破坏了。你需要弄清楚它为什么会坏,正确的算法应该是什么。这不能基于问题中有限的信息来回答,唯一可以简单确定的是原因,以及为什么会出现无限递归的解释;这很明显。

听起来您的函数从未停止递归。您是否考虑过使用调试器跟踪代码或添加一些日志记录,以便了解实际发生的情况?这不是问题所在,但前五个
if
语句的括号太多。您不需要任何内部的。有没有一种方法可以在递归中使用更少的堆栈空间?--到目前为止,您还没有证明问题在于堆栈空间。如果只是代码中的一个bug或逻辑中的一个错误导致了堆栈溢出,而不仅仅是因为您是一个大迷宫,该怎么办?另外,您使用了哪些数据进行了测试?如果您还没有这样做,我建议您使用一个更小的迷宫,以确保这不仅仅是一个bug。确切的错误消息是什么?即使不费力地通过调试器,也有一种简单的技术可以找到递归bug。1) 将递归级别添加到参数列表中。2) 相应地更新递归调用。3) 在函数开始时输出递归级别和键信息。(在这种情况下,x,y,z是理想的。)。。。使用这个技巧,你的bug会像拇指酸痛一样突出。