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

C语言跨函数调用free()释放calloc创建的结构体数组时崩溃

问题原因

你遇到的错误码0xC0000374是Windows系统定义的堆损坏错误,本质是内存操作越界破坏了堆内存的管理元数据,free执行时检测到堆结构异常直接触发崩溃,核心诱因有两个:

  1. calloc分配内存时的元素大小计算完全错误
    原代码中写的是sizeof(propositions),但propositions是函数入参,类型是proposition*(结构体指针),所以这里算出来的大小是指针本身的长度(32位系统下4字节、64位系统下8字节),远小于单个proposition结构体的实际大小。后续往matches数组里写入完整结构体时,会直接超出分配的内存边界,覆盖堆的管理信息,最终导致free崩溃。
  2. strcmp返回值判断存在语义错误
    strcmp匹配相等时返回整数值0,而NULL是空指针常量,虽然数值上两者可能都为0,但把整数返回值和指针常量比较属于不规范写法,存在跨平台/编译环境下的逻辑隐患。
修复方案

按以下两点修改代码即可解决问题:

  • 修正calloc的大小参数:将sizeof(propositions)替换为sizeof(proposition),更稳妥的写法是用sizeof(*matches),后续即使指针类型调整也不会出现大小计算错误。
  • 修正字符串比较的判断条件:将所有strcmp(...) == NULL改为strcmp(...) == 0,符合C标准库函数的语义要求。

修正后的核心代码片段:

proposition* get_matching_propositions(char *pcde, proposition *propositions, int *match_count)
{    
    proposition *matches;
    int         count       = get_count_from_stream(ptf_proposition, sizeof(proposition)),
                cptr_match  = 0;

    for (int i = 0; i < count; i++)
    {
        if (strcmp(propositions[i].cde, pcde) == 0)
        {
            cptr_match++;
        }
    }

    matches = (proposition*) calloc (cptr_match, sizeof(proposition));
    assert(matches != NULL);

    cptr_match = 0;
    for (int i = 0; i < count; i++)
    {
        if (strcmp(propositions[i].cde, pcde) == 0)
        {
            matches[cptr_match] = propositions[i];
            cptr_match++;
        }
    }
    *match_count = cptr_match;
    return matches;
}

修改后分配的内存大小和实际存储需求完全匹配,不会出现越界写堆的问题,free即可正常执行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 20:33:19