C语言使用malloc分配char**内存时出现segmentation fault问题求助
C语言代码问题排查与修复
核心报错原因
你遇到段错误的最直接原因是指针数组的内存分配大小计算错误:
你写的分配代码是:
ingredients = (char**)malloc(numIngredients*sizeof(char));
ingredients是char**类型,指向的是一组char*类型的指针,每个指针占4/8字节(依系统架构而定),而sizeof(char)仅为1字节,分配的内存空间远小于实际需要的大小。后续给ingredients[i]赋值时会越界访问非法内存,直接触发段错误。
修复方式为把分配语句修改为:
// 也可以写成 sizeof(*ingredients) 兼容性更好,修改指针类型时不需要同步改sizeof的参数 ingredients = malloc(numIngredients * sizeof(char*));
其他需要修复的潜在问题
- 无文件打开校验:
fopen执行失败时会返回NULL,后续直接操作空文件指针也会触发段错误,需要增加合法性判断:
in = fopen("input.txt", "r"); if (in == NULL) { perror("读取input.txt失败"); return NULL; }
- 读取逻辑不符合需求:你要求读取文件的一整行作为食材名,但
fscanf的%s格式符遇到空格、制表符就会终止读取,如果食材名包含空格会出现读取截断。建议替换为fgets读取整行,同时注意移除fgets自带的末尾换行符:
fgets(ingredients[i], MAX_ING, in); // 移除末尾换行符 char *newline = strchr(ingredients[i], '\n'); if (newline) *newline = '\0';
- 无内存分配校验:每次
malloc调用后都需要判断返回值是否为NULL,避免内存分配失败后操作空指针。 - 冗余的返回值强制转换:C标准允许
void*隐式转换为任意指针类型,malloc返回值不需要强制转换,多余的转换反而可能隐藏未引入stdlib.h头文件的问题。
修复后完整参考代码
#include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_ING 128 // 可根据实际需求修改大小 char** readIngredients(int numIngredients){ // 入参合法性校验 if (numIngredients <= 0) { return NULL; } FILE *in = fopen("input.txt", "r"); if (in == NULL) { perror("打开input.txt失败"); return NULL; } char** ingredients = malloc(numIngredients * sizeof(*ingredients)); if (ingredients == NULL) { perror("分配指针数组失败"); fclose(in); return NULL; } for(int i=0; i<numIngredients; i++){ ingredients[i] = malloc(MAX_ING * sizeof(char)); if (ingredients[i] == NULL) { perror("分配字符串内存失败"); // 分配失败时释放已申请的内存避免泄漏 for(int j=0; j<i; j++) { free(ingredients[j]); } free(ingredients); fclose(in); return NULL; } // 读取整行 if (fgets(ingredients[i], MAX_ING, in) == NULL) { // 读取失败处理 perror("读取行失败"); for(int j=0; j<=i; j++) { free(ingredients[j]); } free(ingredients); fclose(in); return NULL; } // 移除换行符 char *newline = strchr(ingredients[i], '\n'); if (newline) { *newline = '\0'; } } fclose(in); return ingredients; }
内容的提问来源于stack exchange,提问作者idgit。
相关产品推荐
相关产品推荐

