realloc(): Invalid next size错误求助,附C语言最小可复现示例
解决
realloc(): Invalid next size 错误的分析与修复 咱们一步一步拆解你代码里的问题,这个错误本质是内存越界破坏了堆结构,导致realloc无法正确识别内存块的管理元数据:
核心问题点
未保存
realloc的返回值realloc可能会分配新的内存块并释放旧块,或是在原地扩容。你现在的写法!realloc(buffer, bufsiz *= 2)不仅没把新地址赋值给buffer(原指针可能已失效),还会在realloc成功时触发return 1,逻辑完全搞反了。更糟的是,如果realloc失败返回NULL,你会丢失原buffer指针,造成内存泄漏。数组越界访问
初始bufsiz=4,数组合法索引是0-3。当tmp == bufsiz时,tmp已经是4了,这时候buffer[tmp] = fgetc(stdin)会写入数组的第5个位置,直接越界破坏堆内存的管理信息——这就是realloc报错的直接原因。fgetc返回值类型错误fgetc返回int类型,因为它要通过EOF(值为-1)表示文件结束。如果用char存储,当系统中char是无符号类型时,EOF会被转换成255,循环条件buffer[tmp] = fgetc(stdin)永远为真,会一直写内存直到越界崩溃。未处理
malloc失败的情况
如果malloc返回NULL,后续直接访问buffer[tmp]会导致未定义行为。
修复后的代码
#include <stdio.h> #include <stdlib.h> int main(void) { size_t bufsiz = 4; char *buffer = malloc(bufsiz); // 处理malloc失败的情况 if (!buffer) { perror("malloc failed"); return 1; } int c; size_t tmp = 0; // 用int接收fgetc返回值,先判断是否为EOF while ((c = fgetc(stdin)) != EOF) { // 写入前检查空间,不足则扩容 if (tmp >= bufsiz) { char *new_buf = realloc(buffer, bufsiz *= 2); if (!new_buf) { perror("realloc failed"); free(buffer); // 避免内存泄漏 return 1; } buffer = new_buf; } buffer[tmp++] = (char)c; } // 若需要将buffer作为字符串使用,可添加结束符 // if (tmp < bufsiz) buffer[tmp] = '\0'; free(buffer); return 0; }
修复说明
- 用
int c接收fgetc的返回值,正确识别EOF,避免循环无法终止。 - 先检查
malloc是否成功,杜绝空指针访问。 - 在写入字符前检查空间,当
tmp等于当前bufsiz时先扩容,彻底避免越界。 - 用临时指针接收
realloc返回值,失败时释放原有内存,避免泄漏。 - 最后主动
free内存,养成良好的内存管理习惯。
现在编译运行你的测试命令:
gcc prog.c -o prog echo duck | ./prog
就不会再出现realloc相关错误了。
内容的提问来源于stack exchange,提问作者beardeadclown




