C语言大学项目使用double pointer创建二维数组触发segmentation fault求助
段错误触发核心原因
- 数组索引越界(最高发原因):C语言数组为0起始索引,你代码中直接使用读取到的
linha(行号)、coluna(列号)作为数组下标,但业务输入的行号列号通常是1起始计数的,比如输入3 3 2实际对应数组下标[2][2],如果直接用[3][3]访问,当num_linhas=3、num_colunas=3时,已经超出二维数组的合法访问范围,访问非法内存触发段错误。 - 结构体参数未初始化:如果调用
cria_mapa函数前,没有提前给labirinto结构体的num_linhas、num_colunas、num_paredes成员赋值,会导致malloc/calloc申请的内存大小异常,后续访问数组时必然越界。 - 行内存分配失败未处理:你仅检查了二维数组一级指针
map的malloc返回值,没有检查每一行calloc的返回值,如果某一行内存分配失败,后续访问map[i]就会触发野指针访问。 - 输入值合法性缺失校验:没有校验读取到的
linha、coluna是否为负数、是否超出数组合法范围,非法值会直接导致越界访问。
修复方案
1. 索引转换+输入合法性校验
修改写入数组的逻辑,首先对读取到的行号列号做合法性校验,同时如果输入是1起始的计数,先减1转换为0起始索引:
for(k=0;k<labirinto->num_paredes;k++){ if(fscanf(InputFile1, "%d %d %d", &linha, &coluna, &valor)!=3){ exit(EXIT_FAILURE); // 建议用标准宏代替魔数0 } // 索引转换:如果输入本身是0起始可删除下面两行,仅保留校验逻辑 linha -= 1; coluna -= 1; // 边界校验 if(linha <0 || linha >= labirinto->num_linhas || coluna <0 || coluna >= labirinto->num_colunas){ fprintf(stderr, "非法坐标:%d %d\n", linha+1, coluna+1); exit(EXIT_FAILURE); } labirinto->map[linha][coluna]=valor; fprintf(OutputFile, "%d %d %d\n", linha+1, coluna+1, labirinto->map[linha][coluna]); }
2. 补充行内存分配校验
修改二维数组初始化逻辑,检查每一行的calloc返回值,分配失败时提前释放已申请内存避免泄漏:
for(i=0;i<labirinto->num_linhas;i++){ labirinto->map[i] = (int *) calloc(labirinto->num_colunas, sizeof(int)); if(labirinto->map[i] == NULL){ for(int j=0;j<i;j++){ free(labirinto->map[j]); } free(labirinto->map); exit(EXIT_FAILURE); } }
3. 新增入口参数校验
在cria_mapa入口补充空指针、非法参数校验,提前拦截异常调用:
void cria_mapa(FILE *InputFile1, FILE *OutputFile, labirinto_struct *labirinto){ // 入口基础校验 if(InputFile1 == NULL || OutputFile == NULL || labirinto == NULL){ exit(EXIT_FAILURE); } if(labirinto->num_linhas <=0 || labirinto->num_colunas <=0 || labirinto->num_paredes <=0){ exit(EXIT_FAILURE); } // 原有逻辑 }
内容的提问来源于stack exchange,提问作者Valentim
相关产品推荐
相关产品推荐

