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