C语言实现栈时报malloc(): corrupted top size错误如何解决?
核心问题:扩容判断逻辑完全错误
你代码里push函数的扩容判断存在根本性错误:
if (stk->index + 1 == sizeof(stk->stack)/sizeof(stk->stack[0]))
这里的stk->stack是int*类型的指针,不是数组,sizeof(stk->stack)得到的是指针本身的内存大小(64位系统下为8字节,32位系统下为4字节),这个值是编译期就固定的,和你动态申请的数组长度没有任何关系。
以64位系统为例,sizeof(stk->stack)/sizeof(stk->stack[0])的计算结果固定为8/4=2,也就是说你的扩容条件永远是stk->index +1 ==2,只有第一次push(index从0变成1)的时候会触发一次扩容,后续所有push都不会再触发扩容。
你初始只分配了5个int的空间,第一次扩容到11个int,当push第12个元素的时候就会发生堆缓冲区溢出,直接破坏malloc维护的堆元数据,就会触发你看到的malloc(): corrupted top size报错。
为什么加printf或者不打印就不会报错?
这是C语言里典型的未定义行为的表现:
- 堆溢出的后果和当前堆内存的布局直接相关,如果溢出的位置刚好没有覆盖malloc的关键元数据,程序就不会立刻崩溃
- 加
printf会改变进程的堆内存分配布局(printf内部也会调用malloc申请缓冲区),刚好让你的溢出没有破坏到关键数据,所以看起来运行正常,但代码的错误是客观存在的,随时可能出问题。
修复方案
你需要在Stack结构体里新增一个字段记录当前栈的最大容量,不能用sizeof计算动态数组的长度:
- 修改结构体定义:
typedef struct { int index; // 栈顶下标 int capacity; // 栈的总容量 int* stack; } Stack;
- 修改
getNewStack函数,初始化capacity:
Stack* getNewStack(void) { Stack *temp = (Stack*)malloc(sizeof(Stack)); if (temp == NULL) { printf("Error : Memory allocation failed!\n"); return NULL; } const int init_cap = 5; temp->stack = (int*)malloc(sizeof(int) * init_cap); if (temp->stack == NULL) { printf("Error : Memory allocation failed!\n"); free(temp); // 注意这里要释放已经申请的Stack结构体,避免内存泄漏 return NULL; } temp->index = 0; temp->capacity = init_cap; return temp; }
- 修改
push函数的扩容判断逻辑,同时要检查realloc的返回值:
void push(Stack* stk, const int value) { if (stk == NULL) return; // 栈满时扩容 if (stk->index >= stk->capacity) { int new_cap = stk->capacity + 10; int* new_stack = (int*)realloc(stk->stack, sizeof(int) * new_cap); if (new_stack == NULL) { printf("Error : Memory reallocation failed!\n"); return; } stk->stack = new_stack; stk->capacity = new_cap; } stk->stack[stk->index++] = value; }
- 补充内存释放逻辑,避免内存泄漏:
void freeStack(Stack* stk) { if (stk == NULL) return; free(stk->stack); free(stk); }
主函数最后调用freeStack(new)释放内存即可。
其他需要注意的点
- 不要用
new作为变量名,虽然C语言不报错,但这是C++的关键字,属于不好的编码习惯 realloc失败会返回NULL,直接赋值给原指针会导致原内存地址丢失,造成内存泄漏,必须用临时变量接收返回值,确认成功后再赋值给原指针- 动态分配的内存必须手动释放,避免内存泄漏
- 不要依赖未定义行为的表现,不管加printf后是否正常运行,溢出的问题始终存在
内容的提问来源于stack exchange,提问作者JustAnotherDev
相关产品推荐
相关产品推荐

