You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用fgets时触发Segmentation Fault的问题排查求助

分析与修复C语言文件读取函数的段错误问题

核心错误:realloc参数错误引发内存越界

你的代码中首次调用malloc时正确计算了所需字节数:malloc(sizeof(int) * limit),但后续realloc调用存在致命错误:

values = realloc(values, limit);

realloc的第二个参数要求传入字节数,但你传入的是元素个数limit。当limit增加到201时,realloc仅分配201字节,而实际需要201 * sizeof(int)字节(32位系统下为804字节)。内存分配不足会导致后续写入values[i]时越界,破坏堆内存结构。当循环执行到第106次时,堆结构的损坏已经影响到FILE指针fp或fgets的内部缓冲区,最终触发段错误。

其他潜在问题

  • 未检查fopen返回值:若文件不存在或无权限打开,fp会为NULL,直接调用fgets会触发段错误。
  • 未处理realloc失败场景:realloc内存不足时返回NULL,直接赋值给values会丢失原指针,造成内存泄漏。
  • fgets缓冲区截断风险:若文件中某行数字长度超过DIGITS_MAXIMUM_NUMBER-1,fgets会截断数据,剩余字符留在输入缓冲区,后续读取会得到错误的分段数据。

修正后的代码

#define DIGITS_MAXIMUM_NUMBER 10

int* read_from_file(const char* file_name)
{
    int limit = 101;
    int *values = malloc(sizeof(int) * limit); // C标准中无需强制转换malloc返回值
    if (!values) { // 检查malloc是否成功
        return NULL;
    }

    FILE *fp = fopen(file_name, "r");
    if (!fp) { // 检查文件是否成功打开
        free(values);
        return NULL;
    }

    char string_value[DIGITS_MAXIMUM_NUMBER];
    int i = 1;

    while(fgets(string_value, DIGITS_MAXIMUM_NUMBER, fp) != NULL)
    {
        if (i >= limit) {
            limit += 100;
            int *temp = realloc(values, sizeof(int) * limit); // 传入正确的字节数
            if (!temp) { // 处理realloc失败
                free(values);
                fclose(fp);
                return NULL;
            }
            values = temp;
        }

        values[i] = atoi(string_value);
        i++;
        if (i >= 106)
            printf("%d\n", i);
    }

    values[0] = i;

    // 收缩内存至实际所需大小(失败时保留原指针,避免内存丢失)
    int *temp = realloc(values, sizeof(int) * i);
    if (temp) {
        values = temp;
    }

    fclose(fp);
    return values;
}

内容的提问来源于stack exchange,提问作者Francesco

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 22:20:01