C语言段错误修复:fscanf调用引发崩溃的解决方案
解决PGM文件读取时的Segmentation Fault问题
你遇到的段错误直接出在fscanf(image, "%d", (*M)[i][j]);这一行,结合你的代码和场景,我来拆解问题和修复方案:
1. 最直接的错误:fscanf参数传错了
fscanf读取整数时,第二个参数要求传入整数的内存地址,但你写的(*M)[i][j]是直接取二维数组元素的值(而且代码里循环变量是l和c,这里的i/j应该是笔误)。如果这个值是未初始化的垃圾数据,把它当作地址传给fscanf,必然会触发非法内存访问,也就是段错误。
修正后的代码应该是取元素的地址:
fscanf(image, "%d", &(*M)[l][c]);
2. 必须确认:二维数组的内存分配是否完整
你用了int ***M这种三级指针,说明是动态分配二维数组。如果在调用Store函数前,没有正确完成内存分配,(*M)[l][c]就是野指针,哪怕改了fscanf的参数还是会出错。正确的分配步骤应该是这样的(在调用Store之前执行):
// 第一步:分配存储行指针的数组 *M = malloc(lines * sizeof(int*)); if (*M == NULL) { fprintf(stderr, "Memory allocation failed for rows\n"); exit(EXIT_FAILURE); } // 第二步:为每一行分配存储列元素的空间 for (int l = 0; l < lines; l++) { (*M)[l] = malloc(columns * sizeof(int)); if ((*M)[l] == NULL) { // 分配失败时要释放已分配的内存,避免内存泄漏 for (int k = 0; k < l; k++) { free((*M)[k]); } free(*M); fprintf(stderr, "Memory allocation failed for column %d\n", l); exit(EXIT_FAILURE); } }
3. 额外的PGM格式检查
虽然你说打开文件的功能正常,但要确保已经正确跳过了PGM的头信息:比如魔数P2、注释行(以#开头的行)、图像尺寸和最大灰度值。如果fscanf读取的是头信息里的非数字内容,也可能导致读取异常甚至触发错误。
最后给你一个修正后的完整Store函数示例:
#include <stdio.h> #include <stdlib.h> void Store(int ***M, int lines, int columns, FILE *image) { for(int l = 0; l < lines; l++) { for(int c = 0; c < columns; c++) { // 读取像素值,同时检查读取是否成功 if (fscanf(image, "%d", &(*M)[l][c]) != 1) { fprintf(stderr, "Failed to read pixel at position (%d, %d)\n", l, c); // 这里可以根据需要添加内存释放逻辑 exit(EXIT_FAILURE); } } } }
内容的提问来源于stack exchange,提问作者Andre
相关产品推荐
相关产品推荐

