如何修复迷宫导航程序嵌套循环中的段错误?
问题
开发了一个迷宫导航程序,定位老鼠的环节出现问题。通过指针数组查找迷宫中代表老鼠的'M'的嵌套循环持续触发段错误,错误发生在if (maze[i][j] == 'M')行。
相关代码片段:
void iterative_search(char **maze, int rows, int cols, char *directions) { int x = -1, y = -1; for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { if (maze[i][j] == 'M') { //<- 段错误发生在此处 break; } } if (maze[x][y] == 'M') { break; } } if (x == rows && y == cols) { printf("Error: Jerry not found in the maze.\n"); return; } // 后续移动逻辑... }
完整代码:
#include <stdio.h> #include <stdlib.h> #include <string.h> void iterative_search(char **maze, int rows, int cols, char *directions); int main(int argc, char *argv[]) { if (argc != 3) { printf("Error: Please provide two input files via command line arguments.\n"); return 1; } FILE *maze_file = fopen(argv[1], "r"); FILE *directions_file = fopen(argv[2], "r"); if (!maze_file || !directions_file) { printf("Error: Could not open input files.\n"); return 1; } int rows, cols; // 从文件读取迷宫并存储到二维数组 fscanf(maze_file, "%d %d", &rows, &cols); fgetc(maze_file); // 读取行列数后的换行符 char **maze = malloc(rows * sizeof(char *)); for (int i = 0; i < rows; i++) { maze[i] = malloc((cols + 1) * sizeof(char)); fgets(maze[i], cols + 1, maze_file); } fclose(maze_file); char *directions = NULL; size_t len = 0; ssize_t read; while ((read = getline(&directions, &len, directions_file)) != -1) { iterative_search(maze, rows, cols, directions); } fclose(directions_file); // 将迭代搜索结果写入文件 FILE *iterative_output = fopen("iterative_output.out", "w"); if (iterative_output) { for (int i = 0; i < rows; i++) { fprintf(iterative_output, "%s", maze[i]); } fclose(iterative_output); } else { printf("Error: Could not create iterative_output.out file.\n"); } // 释放动态分配的内存并关闭文件 for (int i = 0; i < rows; i++) { free(maze[i]); } free(maze); return 0; }
问题分析与修复方案
核心错误点
- 未记录'M'的坐标:找到'M'后仅终止内层循环,但未将当前的
i和j赋值给x、y,后续执行maze[x][y]时,x和y还是初始值-1,访问非法内存直接触发段错误。 - 错误的终止判断逻辑:查找结束后判断
x == rows && y == cols完全不合理,x和y的合法范围是0~rows-1、0~cols-1,这个条件永远不会成立,无法正确检测'M'未找到的情况。 - 嵌套循环未完全终止:找到'M'后内层循环终止,但外层循环仍会继续执行,做无用功。
修复后的iterative_search函数
void iterative_search(char **maze, int rows, int cols, char *directions) { int x = -1, y = -1; // 查找老鼠'M'的位置 for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { if (maze[i][j] == 'M') { x = i; y = j; goto found; // 找到后直接跳出所有循环 } } } found: // 判断是否找到'M' if (x == -1 || y == -1) { printf("Error: Jerry not found in the maze.\n"); return; } // 执行移动逻辑 for (int i = 0; directions[i] != '\0'; i++) { // 跳过换行符(getline读取的行包含末尾的'\n') if (directions[i] == '\n') continue; int new_x = x; int new_y = y; switch (directions[i]) { case 'N': new_x--; break; case 'E': new_y++; break; case 'S': new_x++; break; case 'W': new_y--; break; default: continue; } // 检查新位置是否合法 if (new_x >= 0 && new_y >= 0 && new_x < rows && new_y < cols && (maze[new_x][new_y] == ' ' || maze[new_x][new_y] == 'C')) { // 标记走过的路径(初始位置'M'保留) if (maze[x][y] != 'M') { maze[x][y] = '.'; } x = new_x; y = new_y; // 检查是否找到奶酪 if (maze[x][y] == 'C') { printf("Jerry found the cheese at (%d, %d)!\n", x, y); break; } } } }
额外优化点
- 处理了
directions中的换行符:getline会读取到行末尾的\n,跳过该字符避免无效移动指令。 - 使用
goto直接跳出嵌套循环,在这种场景下比多层break更清晰高效。 - 修正了'M'未找到的判断逻辑,改为检测
x或y是否仍为初始值-1。
内容的提问来源于stack exchange,提问作者seopr
相关产品推荐
相关产品推荐

