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

C语言读取文件存入结构体数组报corrupted size vs. prev_size错误求解

错误原因分析

核心诱因:堆缓冲区溢出(数组越界写入)

  • 你使用while(!feof(fin))作为循环判断条件是错误的:feof()的作用是判断上一次读取操作是否已经触发了文件结束标记,而非提前预判是否还有内容可读。你的示例文件共3行,countLines()返回3,你申请了长度为3的JOB数组,但循环会多执行1次:当读完第3行内容后,feof()仍未置位,会进入第4次循环,向arr[3](数组下标从0开始,合法下标仅0、1、2)写入数据,直接越界破坏了堆块的元数据,这就是你看到corrupted size vs. prev_size错误的直接原因。

其他潜在逻辑隐患

  • fscanf(fin, "%d", &arr[k].code)执行后直接调用fgetc(fin)跳过分隔符:如果数字后面的分隔符不是单个空格(比如是制表符、多个空格),或者文件末尾没有换行符,这个操作会读取到后续有效内容的第一个字符,导致数据读取错乱。
  • 调用fgets读取完一行后直接执行buf[strlen(buf) - 1] = '\0'删除换行:如果读取到的行是文件最后一行且末尾没有换行符,该操作会将行尾的有效字符删除,甚至当fgets读取失败时strlen(buf)返回0,会出现buf[-1]的非法访问。

修复方案

你可以将读取循环替换为以下逻辑,从根源避免越界和读取异常:

int k = 0;
char buf[MAXLINESIZE];
// 直接判断fscanf的返回值,成功读取到1个整数、且未超过数组长度才继续后续操作
while (k < nEntries && fscanf(fin, "%d ", &arr[k].code) == 1) {
    // %d后面加空格会自动跳过所有空白字符,不需要单独调用fgetc
    if (fgets(buf, sizeof(buf), fin) != NULL) {
        // 安全删除末尾的换行符
        size_t len = strlen(buf);
        if (len > 0 && buf[len - 1] == '\n') {
            buf[len - 1] = '\0';
        }
        arr[k].name = strdup(buf);
        k++;
    }
}

额外注意:程序退出前需要遍历数组,逐个free每个name指针,再free数组本身,避免内存泄漏。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 00:27:05