AddressSanitizer报SEGV未知错误,读取文件实现矩阵乘法时fscanf报错
段错误原因及修复方案
1 触发SEGV的直接原因
你只完成了二级矩阵的第一层内存分配,没有为每一行的元素分配内存:
- 代码中
int **matrixOne = (int **)malloc(size * sizeof(int *));只分配了存储size个行指针的内存空间,每个matrixOne[i]都是未初始化的野指针 - 当执行
&m1[i][j]时,本质是先访问野指针m1[i]再偏移j个int位置,直接访问非法内存,触发段错误
2 读取文件逻辑的问题
你理解的「读取完size后fscanf会从第一个矩阵元素开始扫描」逻辑本身是成立的,fscanf读取%d时会自动跳过空格、换行、制表符等空白字符,但你的代码存在两个缺陷:
- 你的输入文件带
//注释,fscanf不会跳过注释内容,读取完size后下一个字符是/,不符合%d的格式要求,会读取失败,你没有判断fscanf的返回值,后续逻辑会拿到非法值 - 没有判断
fopen的返回值,如果传入的文件路径错误、文件不存在,file为NULL,调用fscanf也会触发段错误
3 修复方案
3.1 补全矩阵内存分配
在main函数中分配完行指针数组后,为每一行分配元素内存:
int **matrixOne = (int **)malloc(size * sizeof(int *)); int **matrixTwo = (int **)malloc(size * sizeof(int *)); int **result = (int **)malloc(size * sizeof(int *)); // 新增行内存分配 for(int i=0; i<size; i++){ matrixOne[i] = malloc(size * sizeof(int)); matrixTwo[i] = malloc(size * sizeof(int)); result[i] = malloc(size * sizeof(int)); }
3.2 优化文件读取逻辑
- 要么删除输入文件中的所有
//注释,要么读取时先跳过注释内容,比如每次读取前跳过所有非数字字符 - 新增
fopen失败判断:if(file == NULL) { perror("文件打开失败"); return 1; } - 每次调用
fscanf后判断返回值是否为预期的成功读取数,避免读取失败的脏数据影响后续逻辑 - 程序结束前调用
fclose(file)关闭文件,循环释放所有矩阵的行内存和二级指针内存,避免内存泄漏
内容的提问来源于stack exchange,提问作者Kush Patel
相关产品推荐
相关产品推荐

