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
相关产品推荐
相关产品推荐

