我正在尝试为迷宫创建BFS,该迷宫将在到达特定点时停止。在测试时,我遇到了分段错误(核心转储)错误。我正在尝试修改在此site上找到的代码。我要执行的操作与该站点中的代码之间的主要区别是,我不需要输出行进的距离,因此我也应该在顶点在矩阵内部的队列中输出顺序。例如,输出应为以下内容:
What the output of the program should be
由于此错误使我无法继续前进,因此哈希值表示尚未添加到队列中的顶点,到目前为止,我对此不太担心。
到目前为止,这是我的代码:
#include <queue>
#include <iostream>
#include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
#define ROW 8
#define COL 11
struct Point{
int x;
int y;
};
bool isValid(int x, int y)
{
// return true if row number and column number
// is in range
return (x >= 0) && (x< ROW) &&
(y >= 0) && (y < COL);
}
int rowNum[] = {-1, 0, 0, 1};
int colNum[] = {0, -1, 1, 0};
int BFS(int mat[][COL], Point src, Point dest)
{
int order = 1;
// Mark the source cell as visited
bool visited[ROW][COL];
memset(visited, false, sizeof visited);
visited[src.x][src.y] = true;
// Create a queue for BFS
queue <Point> vertices;
// Enqueue source cell
vertices.push(src);
// Do a BFS starting from source cell
while(visited[dest.x][dest.y] != true){
Point current = vertices.front();
vertices.pop();
for (int i = 0; i < 4; i++)
{
int row = current.x + rowNum[i];
int col = current.y + colNum[i];
// if adjacent cell is valid, has path and
// not visited yet, enqueue it.
if (isValid(row, col) == true && (mat[row][col]) &&
!visited[row][col])
{
cout << "Hi" << endl;
// mark cell as visited and enqueue it
visited[row][col] = true;
mat[row][col] = order;
order++;
vertices.push(current);
cout << vertices.front().x;
cout << vertices.front().y;
}
else {
}
}
}
return -1;
}
int main()
{
int mat[ROW][COL] =
{
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
};
Point source = {0, 0};
Point dest = {3, 4};
BFS(mat, source, dest);
for (int i = 0; i < ROW; ++i)
{
for (int j = 0; j < COL; ++j)
{
std::cout << mat[i][j] << ' ';
}
std::cout << std::endl;
}
return 0;
}
我事先做了一些故障排除,发现错误很可能是由此位置引起的:
if (isValid(row, col) == true && (mat[row][col]) &&
!visited[row][col])
{
// mark cell as visited and enqueue it
visited[row][col] = true;
mat[row][col] = order;
order++;
vertices.push(current);
cout << vertices.front().x;
cout << vertices.front().y;
}
我认为,因为我设置了一堆输出消息(您可能会注意到提示“ Hi's”)会在原因中的某些点发生,从而找到错误的根源,而这正是导致我的原因。
我们非常感谢您的帮助,为清楚起见,我试图找出为什么我会遇到细分错误。
谢谢。
答案 0 :(得分:2)
啊,可怕的segmentation fault
是编程中最好的错误之一!登录到stdout
是一种调试方式,但是您可以使用调试器(例如gdb
)来简化自己的生活。
比方说,您的可执行文件名为bfs
,它产生了一个名为core.bfs.12345
的核心转储(12345
是进程的PID)。像这样调用gdb
:
$ gdb ./bfs core.bfs.12345
输入后,gdb
会立即告诉您程序崩溃的位置-无需打印语句!它应该是这样的:
Program terminated with signal 11, Segmentation fault.
#0 0x0000000000400d3e in BFS (mat=0x7fffffffd950, src=..., dest=...) at ../bfs/bfs.cxx:54
54 Point current = vertices.front();
从本质上讲,这是在告诉您呼叫queue<Point>::front()
的第54行(您的行号可能不同)。但是,如果队列为空,则调用front()
是未定义的行为。
您的其余代码似乎已经步入正轨。我鼓励您重新考虑while
循环条件。也许,有一种“更安全”的方式来知道是否继续搜索。