为什么我会遇到分段错误以及如何修复它?
我正在编写下面的代码,通过迷宫递归“遍历”并找到路径的总数。我正在使用堆栈来跟踪“下一步”。
ROWS和COLUMNS定义迷宫的大小。如果我将这些参数设置为大于9x9,则会出现分段错误。我不知道为什么我会这样做。
这是我第一次使用gdb并获得以下内容:
#3 0x0000000000400de0 in std::stack<xy, std::deque<xy, std::allocator<xy> > >::top (this=0x604400 <buff>)
at /usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.2/../../../../include/c++/4.7.2/bits/stl_stack.h:161
161 return c.back();
让我相信它与我的筹码有关。
我感谢任何帮助。感谢。
守则:
#define ROWS 10
#define COLUMNS 10
#include<iostream>
#include<stack>
using namespace std;
struct xy
{
long i;
long j;
};
stack<xy> buff;
long goRight (long j)
{
if (j < COLUMNS-1)
return 1;
else
return 0;
}
long goDown (long i)
{
if (i < ROWS-1)
return 1;
else
return 0;
}
long traverse (xy POS)
{
long fD = goDown(POS.i);
long fR = goRight(POS.j);
xy toAdd;
if (fD == 1)
{
toAdd.i=POS.i+1;
toAdd.j=POS.j;
buff.push(toAdd);
}
if (fR == 1)
{
toAdd.i=POS.i;
toAdd.j=POS.j+1;
buff.push(toAdd);
}
if(buff.empty())
return 0;
toAdd = buff.top();
buff.pop();
return (traverse(toAdd) + (fD * fR));
}
int main()
{
xy initial;
initial.i=0;
initial.j=0;
cout << 1 + traverse(initial);
return 1;
}
答案 0 :(得分:1)
您的call stack
内存有限,您调用的每个函数都在该堆栈上使用内存。因此,通过一个巨大的迷宫递归强制将最终以 stack overflow 结束。使用gdb的backtrace函数应该清楚地显示出来。
您应该重新考虑算法并使用迭代而不是递归。 在您的情况下,您似乎想要实现某种flood fill algorithm,这很容易通过迭代来完成,如link中所述。
另请注意,如果您使用的是Linux系统,使用ulimit -s unlimited
将允许您为从此终端仿真程序运行的所有程序使用call stack
的无限量内存。那么你的程序不应该是段错误的。
答案 1 :(得分:0)
我相信你不需要一个std::stack
对象来实现你想要的(即计算路径数)。而且你不一定要切换到迭代,这使得这个算法更难写,只是简化了算法及其终止条件。
这是一个可能的解决方案(顺便说一下,如果你打算用行数和列数来更高,可以考虑切换到long long
以避免整数 - 不是堆栈 - 溢出):
#define ROWS 10
#define COLUMNS 10
#include<iostream>
#include <stack>
using namespace std;
struct xy
{
long i;
long j;
};
stack<xy> partialPath;
long goRight (long j)
{
if (j < COLUMNS - 1)
return 1;
else
return 0;
}
long goDown (long i)
{
if (i < ROWS - 1)
return 1;
else
return 0;
}
long traverse (xy const& POS)
{
partialPath.push(POS); // Not needed to count the # of paths, but if you want...
long fD = goDown(POS.i);
long fR = goRight(POS.j);
xy nextPos;
long numOfPaths = 0;
if (fD == 1)
{
nextPos.i=POS.i+1;
nextPos.j=POS.j;
numOfPaths += traverse(nextPos);
}
if (fR == 1)
{
nextPos.i=POS.i;
nextPos.j=POS.j+1;
numOfPaths += traverse(nextPos);
}
partialPath.pop(); // Not needed to count the # of paths, but if you want...
if ((fD == 0) && (fR == 0))
{
return 1;
}
return numOfPaths;
}
int main()
{
xy initial;
initial.i=0;
initial.j=0;
cout << traverse(initial);
return 0;
}
P.S:为了进一步提高效率,最好通过const ref传递POS
参数。另外,我认为用于指示您的流程成功的返回码应为0而不是1(我的意思是return
main()
语句中的。{/ p>