GDB调试矩阵文件读取代码时出现段错误问题求助
问题分析与修复
你的代码存在三个核心问题,直接导致了段错误和读取异常:
1. 二维数组首段内存分配错误
在readFile函数中,分配指针数组时误用了sizeof(int),但实际上需要分配的是指针的大小(sizeof(int*)):
// 错误写法 int** mat = (int**)malloc(num * sizeof(int)); // 正确写法 int** mat = (int**)malloc(num * sizeof(int*));
原代码分配的内存空间不足以存储num个int*指针,会导致后续给mat[index]赋值时内存越界,破坏堆结构,最终在printMatrix访问时触发段错误。
2. 矩阵读取循环逻辑错误
col变量在循环外部初始化,第一次外层循环(row=0)执行完后,col已经等于num,后续外层循环(row≥1)时,内层循环的col < num条件直接不成立,导致后续行的数据完全未被读取,这些行的内存是未初始化的垃圾值,访问时会引发段错误或输出异常。
修正循环,将col的初始化放到外层循环内部:
int row = 0; for(; row < num; row++) { int col = 0; // 每次切换行时重置col for(; col < num; col++) { fscanf(fp, "%d", &mat[row][col]); } }
3. 缺少文件有效性检查
main函数中调用fopen后未判断文件是否成功打开,如果传入的文件名错误或文件不存在,fp会是NULL,后续fscanf操作会直接崩溃。添加检查逻辑:
FILE* fp = fopen(argv[1], "r"); if (fp == NULL) { fprintf(stderr, "无法打开目标文件\n"); return 1; }
完整修正后的代码
main 函数
#include <stdio.h> #include <stdlib.h> int** readFile(FILE* fp, int *size); void printMatrix(int** mat, int num); int main(int argc, char* argv[]) { if (argc < 2) { fprintf(stderr, "请传入文件名参数\n"); return 1; } FILE* fp = fopen(argv[1], "r"); if (fp == NULL) { fprintf(stderr, "无法打开目标文件\n"); return 1; } int size = 0; int **mat = readFile(fp, &size); printMatrix(mat, size); // 释放内存,避免泄漏 for (int i = 0; i < size; i++) { free(mat[i]); } free(mat); fclose(fp); return 0; }
readFile 函数
int** readFile(FILE* fp, int *size) { if (fscanf(fp, "%d", size) != 1) { fprintf(stderr, "读取矩阵大小失败\n"); return NULL; } int num = *size; int index = 0; int** mat = (int**)malloc(num * sizeof(int*)); if (mat == NULL) { fprintf(stderr, "内存分配失败\n"); return NULL; } for(index = 0; index < num; index++) { mat[index] = (int*)malloc(num * sizeof(int)); if (mat[index] == NULL) { // 分配失败时回滚已分配内存 for (int i = 0; i < index; i++) { free(mat[i]); } free(mat); fprintf(stderr, "内存分配失败\n"); return NULL; } } int row = 0; for(; row < num; row++) { int col = 0; for(; col < num; col++) { if (fscanf(fp, "%d", &mat[row][col]) != 1) { fprintf(stderr, "读取矩阵数据失败\n"); // 回滚内存 for (int i = 0; i < num; i++) { free(mat[i]); } free(mat); return NULL; } } } return mat; }
printMatrix 函数
void printMatrix(int** mat, int num) { if (mat == NULL || num <= 0) { fprintf(stderr, "无效的矩阵参数\n"); return; } int row = 0; int col = 0; for(row = 0; row < num; row++) { for(col = 0; col < num; col++) { printf("%.2d\t", mat[row][col]); } printf("\n"); } }
额外补充:修正后的代码添加了内存分配失败的回滚逻辑和资源释放操作,避免内存泄漏和异常崩溃,这是工业级代码的基本规范。
内容的提问来源于stack exchange,提问作者Noah Nininger
相关产品推荐
相关产品推荐

