动态分配二维数组时出现内存访问违规问题求助
解决动态二维数组赋值时的内存访问违规问题
问题分析
你的代码里有几个关键问题会导致内存访问违规或输入异常:
- scanf格式字符串错误:
scanf("%d\n", &maze[i][j])里的\n完全多余。scanf的格式字符串中,空白字符(包括换行、空格)会让它跳过所有连续空白,直到读取到非空白字符。这会导致输入到最后一列时,程序一直等待额外输入,甚至在输入结束时触发未定义行为。 - 未检查内存分配结果:malloc可能因内存不足返回NULL,如果直接访问
maze[i]或maze[i][j],会直接触发内存访问违规。 - 输入范围逻辑冗余:原本的条件判断可以简化,只对需要输入的区域(i从1到m,j从1到n)进行读取,避免多余的判断。
修正后的代码
#include <stdio.h> #include <stdlib.h> int main() { int m, n; // 检查输入是否有效 if (scanf("%d%d", &m, &n) != 2) { printf("输入错误\n"); return 1; } // 分配行指针数组,检查分配是否成功 int** maze = malloc(sizeof(int*) * (m + 2)); if (maze == NULL) { printf("内存分配失败\n"); return 1; } // 分配每一行的内存,检查分配是否成功,失败则释放已分配内存 for (int i = 0; i < m + 2; i++) { maze[i] = malloc(sizeof(int) * (n + 2)); if (maze[i] == NULL) { printf("内存分配失败\n"); for (int k = 0; k < i; k++) { free(maze[k]); } free(maze); return 1; } } // 初始化上下左右边界为1 for (int i = 0; i < m + 2; i++) { maze[i][0] = 1; maze[i][n + 1] = 1; } for (int j = 0; j < n + 2; j++) { maze[0][j] = 1; maze[m + 1][j] = 1; } // 读取中间区域的输入值 for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { if (scanf("%d", &maze[i][j]) != 1) { printf("输入错误\n"); // 清理已分配内存 for (int k = 0; k < m + 2; k++) { free(maze[k]); } free(maze); return 1; } } } // 打印最终的二维数组 for (int i = 0; i < m + 2; i++) { for (int j = 0; j < n + 2; j++) { if (j == n + 1) { printf("%d\n", maze[i][j]); } else { printf("%d ", maze[i][j]); } } } // 释放所有动态分配的内存 for (int i = 0; i < m + 2; i++) { free(maze[i]); } free(maze); return 0; }
关键修改说明
- 移除scanf中的
\n:统一使用scanf("%d", &maze[i][j]),保证输入流程正常执行。 - 添加内存分配检查:每次调用malloc后都判断是否返回NULL,避免访问空指针;分配失败时会释放已分配的内存,防止内存泄漏。
- 优化边界初始化:单独初始化四个边界,比嵌套循环的条件判断更清晰高效。
- 限制输入范围:仅对需要输入的区域读取数据,减少不必要的条件判断逻辑。
- 添加输入有效性检查:通过scanf的返回值判断输入是否为有效整数,避免非法输入导致程序异常。
- 添加内存释放步骤:程序结束前释放所有动态分配的内存,杜绝内存泄漏。
内容的提问来源于stack exchange,提问作者Louis Sun
相关产品推荐
相关产品推荐

