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

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计算动态数组的长度:

  1. 修改结构体定义:
typedef struct 
{
    int index; // 栈顶下标
    int capacity; // 栈的总容量
    int* stack;
} Stack;
  1. 修改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;
}
  1. 修改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;
}
  1. 补充内存释放逻辑,避免内存泄漏:
void freeStack(Stack* stk)
{
    if (stk == NULL)
        return;
    free(stk->stack);
    free(stk);
}

主函数最后调用freeStack(new)释放内存即可。

其他需要注意的点

  • 不要用new作为变量名,虽然C语言不报错,但这是C++的关键字,属于不好的编码习惯
  • realloc失败会返回NULL,直接赋值给原指针会导致原内存地址丢失,造成内存泄漏,必须用临时变量接收返回值,确认成功后再赋值给原指针
  • 动态分配的内存必须手动释放,避免内存泄漏
  • 不要依赖未定义行为的表现,不管加printf后是否正常运行,溢出的问题始终存在

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 09:45:03