if语句在C中导致“Segmentation fault:11”

时间:2016-02-24 15:13:46

标签: c segmentation-fault maze

此代码的目的是使用回溯算法来解决迷宫问题。 为该算法给出的伪代码是:

read in the maze;
initialize the list;
goalCell = the position of the escape hatch in the maze;
startCell = the initial position of the mouse in the maze;
currentCell = startCell;
while currentCell is not the goalCell
  mark currentCell as visited;
  add to the list the unvisited open neighbours of currentCell;
  if the list is empty
    the mouse is trapped: we tried all routes and failed to find an escape;
  else
    get the next cell from the list and make it currentCell;
end while;
the mouse can escape the maze: we reached the goal cell.

无论我尝试什么,我的代码都不会超过星号。我在没有if语句的情况下运行它,它仍然没有超过那一行。

我在终端编译它,它没有显示任何错误或警告。在终端中运行后,输出为:

1 1 1 1 1  
1 0 0 e 1  
1 1 1 0 1  
1 m 1 0 1  
1 0 0 0 1  
1 1 1 1 1  

1 1 1 1 1  
1 0 0 e 1  
1 1 1 0 1  
1 . 1 0 1  
1 0 0 0 1  
1 1 1 1 1  
Segmentation fault: 11

文件“testMaze.txt”如下:

6 5
1 1 1 1 1
1 0 0 e 1
1 1 1 0 1
1 m 1 0 1
1 0 0 0 1
1 1 1 1 1

我添加了:     printf(“mazeRows是%d,unvisitedCell.row是%d \ n”,mazeRows,unvisitedCell.row);

assert( unvisitedCell.row < mazeRows );
assert( unvisitedCell.column < mazeCols );

printf( "the char is %c\n", maze[unvisitedCell.row][unvisitedCell.column] );

并将if语句更改为:

if ( maze[unvisitedCell.row][unvisitedCell.column] == '0' ) 

并在终端中运行它。我得到的输出是:

1 1 1 1 1  
1 0 0 e 1  
1 1 1 0 1  
1 m 1 0 1  
1 0 0 0 1  
1 1 1 1 1  

1 1 1 1 1  
1 0 0 e 1  
1 1 1 0 1  
1 . 1 0 1  
1 0 0 0 1  
1 1 1 1 1  
mazeRows is 5, and unvisitedCell.row is 4
the char is 0
Segmentation fault: 11

使用Xcode编写的整个代码是:

#include "Maze.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

//-------------------------------------------------------------------------------------
// CONSTANTS and TYPES
//-------------------------------------------------------------------------------------

#define MAX_DIMENSION 20

// constant definitions for the different cell states
const char WALL    = '1';
const char SPACE   = '0';
const char VISITED = '.';
const char MOUSE   = 'm';
const char EXIT    = 'e';

typedef enum BOOL { false, true } Boolean;

struct CELL
{
    int row;
    int column;
};

typedef struct CELL Cell;

typedef struct CELL_NODE CellNode;

struct CELL_NODE
{
    Cell     cell;
    CellNode *next;
};

//-------------------------------------------------------------------------------------
// VARIABLES
//-------------------------------------------------------------------------------------

CellNode *top = NULL;

// a 2D array used to store the maze
char maze[MAX_DIMENSION][MAX_DIMENSION];
int mazeRows;
int mazeCols;

// holds the location of the mouse and escape hatch
Cell mouse;
Cell escape;

//-------------------------------------------------------------------------------------
// PROTOTYPES
//-------------------------------------------------------------------------------------

// basic cell manipulation
Boolean equalCells(const Cell cell1, const Cell cell2);
Cell makeCell(const int row, const int col);
Boolean validCell(const Cell theCell);

// routines for managing our backtracking
Boolean noMoreCells();
Cell nextCell();
void addCell(const Cell cell);

void printMaze();
void loadMaze();

Boolean solveMaze();

// our invariant checker
void checkState();

//-------------------------------------------------------------------------------------
// FUNCTIONS
//-------------------------------------------------------------------------------------

int main( int argc, char *argv[] )
{
    loadMaze();
    printMaze();

    if ( solveMaze() )
        printf( "The mouse is free!!!!\n" );
    else
        printf( "The mouse is trapped!!!!\n" );

    printf( "\nEnd of processing\n" );

    return EXIT_SUCCESS;
}


//////////////////////////////////////////////
// Cell routines
//////////////////////////////////////////////

Boolean equalCells( const Cell cell1, const Cell cell2 )
{
    //assert( cell1.row != cell2.row && cell1.column != cell2.column );

    if ( cell1.row == cell2.row && cell1.column == cell2.column )
        return true;
    else
        return false;
}

Cell makeCell( const int row, const int col )
{
    Cell newCell;
    newCell.row = row;
    newCell.column = col;

    return newCell;
}

Boolean validCell( const Cell theCell )
{
    if ( theCell.row < mazeRows && theCell.column < mazeCols )
        return true;
    else
        return false;
}

Boolean noMoreCells()
{
    if ( top->next == NULL )
        return true;
    else
        return false;
}

Cell nextCell()
{
    return top->cell;
}

void addCell( const Cell cell )
{
    CellNode *cellToAdd = NULL;

    cellToAdd->cell = cell;
    cellToAdd->next = top;

    top->next = cellToAdd;
}

//////////////////////////////////////////////
// List routines
//////////////////////////////////////////////

Boolean solveMaze()
{
    Boolean solved = false;
    CellNode *mazePaths = NULL, *cellToAdd = NULL;
    Cell currentCell, unvisitedCell;
    char ch, position;
    int row, col;

    for ( row = 0; row < mazeRows; row++ )      //checked and works
    {
        for ( col = 0; col < mazeCols; col++ )
        {
            ch = maze[row][col];

            if ( ch == 'm' )
            {
                mouse.row = row;
                mouse.column = col;

                currentCell.row = row;
                currentCell.column = col;
            }
            else if ( ch == 'e' )
            {
                escape.row = row;
                escape.column = col;
            }
        }
    }

    while ( maze[currentCell.row][currentCell.column] != maze[escape.row][escape.column] )
    {
        maze[currentCell.row][currentCell.column] = '.';

        printf("\n");
        printMaze();

        //if the one below current
        unvisitedCell.row = currentCell.row + 1;        //works
        unvisitedCell.column = currentCell.column;      //works

        printf("mazeRows is %d, and unvisitedCell.row is %d\n", mazeRows, unvisitedCell.row );

        assert( unvisitedCell.row < mazeRows );
        assert( unvisitedCell.column < mazeCols );

        printf( "the char is %c\n", maze[unvisitedCell.row][unvisitedCell.column] );

        if ( maze[unvisitedCell.row][unvisitedCell.column] == '0' )      //gives "Segmentation fault: 11"
        {
    ***************************************************************************
            printf("gets into first if");
            cellToAdd->cell = unvisitedCell;
            cellToAdd->next = top;

            mazePaths->next = cellToAdd;

            maze[unvisitedCell.row][unvisitedCell.column] = 'A';
        }

        //if one above current
        unvisitedCell.row = currentCell.row - 1;
        unvisitedCell.column = currentCell.column;

        position = maze[unvisitedCell.row][unvisitedCell.column];
        printf("the pos is %c\n", position);

        if ( position == '0' )
        {
            printf("gets into second if");
            cellToAdd->cell = unvisitedCell;
            cellToAdd->next = top;

            mazePaths->next = cellToAdd;

            maze[unvisitedCell.row][unvisitedCell.column] = 'B';
        }

        //if one to the right of current
        unvisitedCell.row = currentCell.row;
        unvisitedCell.column = currentCell.column + 1;

        position = maze[unvisitedCell.row][unvisitedCell.column];
        printf("the pos is %c\n", position);

        if ( position == '0' )
        {
            printf("gets into third if");
            cellToAdd->cell = unvisitedCell;
            cellToAdd->next = top;

            mazePaths->next = cellToAdd;

            maze[unvisitedCell.row][unvisitedCell.column] = 'R';
        }

        //if one to the left of current
        unvisitedCell.row = currentCell.row;
        unvisitedCell.column = currentCell.column - 1;

        position = maze[unvisitedCell.row][unvisitedCell.column];
        printf("the pos is %c\n", position);

        if ( position == '0' )
        {
            printf("gets into fourth if");
            cellToAdd->cell = unvisitedCell;
            cellToAdd->next = top;

            mazePaths->next = cellToAdd;

            maze[unvisitedCell.row][unvisitedCell.column] = 'L';
        }

        if ( noMoreCells() )
        {
            printf( "The mouse is trapped: we tried all routes and failed to find an escape!" );
        }
        else
        {
            printf("there are still more cells\n");
            currentCell.row = mazePaths->cell.row;
            currentCell.column = mazePaths->cell.column;
        }
    }

    return solved;
}

void checkState()
{
}


//////////////////////////////////////////////
// Maze routines
//////////////////////////////////////////////

void loadMaze()     //checked and works
{
    char input[MAX_DIMENSION];
    char ch;
    int column, index, stringIndex;
    char *line = NULL;
    size_t buffer = MAX_DIMENSION;
    FILE *maze_input = fopen( "testMaze.txt", "r" );

    getline( &line, &buffer, maze_input );

    //to find columns
    stringIndex = 0;
    index = 0;
    ch = line[index];

    while ( ch != ' ' )
    {
        input[stringIndex] = ch;
        stringIndex++;
        index++;
        ch = line[index];
    }

    mazeCols = atoi( input );

    //to find rows
    stringIndex = 0;
    ch = line[index];

    while ( ch != '\0' )
    {
        input[stringIndex] = ch;
        stringIndex++;
        index++;
        ch = line[index];
    }

    mazeRows = atoi( input );

    //reads in the actual maze
    for ( int row = 0; row <= mazeRows; row++ )
    {
        getline( &line, &buffer, maze_input );

        ch = line[0];
        column = 0;
        index = 0;

        while ( ch != '\0' )
        {
            maze[row][column] = ch;

            index += 2;
            column++;
            ch = line[index];
        }
    }
}

void printMaze()    //checked and works
{
    for ( int row = 0; row <= mazeRows; row++ )
    {
        for ( int column = 0; column < mazeCols; column++ )
        {
            printf( "%c ", maze[row][column] );
        }

        printf( "\n" );
    }
}

1 个答案:

答案 0 :(得分:1)

如果此处发生分段错误,则表示您尝试从边界外的2d阵列访问数据。以下行导致分段错误。

position = maze[unvisitedCell.row][unvisitedCell.column];

您需要调试程序,确保unvisitedCell.rowunvisitedCell.column小于最大尺寸(MAX_DIMENSIONMAX_DIMENSION)。

另请注意:

您的指针cellToAdd初始化为NULL,但永远不会初始化为指向CellNode

因此,您正试图在NULL语句if语句后立即访问cellToAdd->cell = unvisitedCell;指针。这将导致另一个分段错误。

请注意,mazePaths

存在同样的问题