B迷宫C ++分段错误错误

时间:2019-01-24 21:44:52

标签: c++ queue breadth-first-search

我正在尝试为迷宫创建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”)会在原因中的某些点发生,从而找到错误的根源,而这正是导致我的原因。

我们非常感谢您的帮助,为清楚起见,我试图找出为什么我会遇到细分错误。

谢谢。

1 个答案:

答案 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循环条件。也许,有一种“更安全”的方式来知道是否继续搜索。