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

C语言代码未调用free()也可正常运行,该写法是否合规?

内存释放逻辑说明

你不能在ft_append内部释放newstr的原因很明确:*str = newstr已经把newstr指向的内存地址赋值给了外部传入的指针,这块内存后续还要在main函数中使用,提前释放会导致后续访问非法内存,自然无法正常输出。

你当前的代码还存在两个未定义行为/隐患:

  • main函数中定义的char *str没有初始化,属于野指针,其值是随机的,不一定为NULL。你在ft_strlen中判断if(str)的逻辑只有在str为NULL时才生效,野指针会大概率触发非法内存访问崩溃,你现在能正常运行只是巧合,必须改为char *str = NULL;
  • 每次ft_append申请新内存拷贝完旧字符串内容后,旧字符串对应的内存没有被释放,会产生内存泄漏。

正确实现代码

修正后的ft_append逻辑如下,只需要释放已经没用的旧内存即可:

void ft_append(char **str, char c)
{
    int len = ft_strlen(*str);
    char *old_str = *str; // 保存旧内存地址
    char *newstr = malloc(len + 2);
    // 增加malloc失败判断,避免空指针访问
    if (!newstr) {
        perror("malloc申请内存失败");
        return;
    }
    int i = 0;
    if (len != 0)
    {
        while (i < len)
        {
            newstr[i] = old_str[i];
            i++;
        }
    }
    newstr[i] = c;
    newstr[i + 1] = '\0';
    *str = newstr;
    free(old_str); // 释放已经不需要的旧内存,free(NULL)是C标准允许的安全操作
}

main函数的修正和最终释放逻辑:

int main()
{
    char *str = NULL; // 必须初始化为NULL
    ft_append(&str, 'x');
    ft_append(&str, 'y');
    ft_append(&str, 'z');
    printf("str = %s\n", str);
    free(str); // 所有使用结束后再释放最终拼接好的字符串内存
    return 0;
}

核心原则总结

malloc申请的堆内存释放的唯一标准:确认这块内存后续不会被任何指针访问时,才可以调用free释放。

  • newstr对应的内存需要返回给外部使用,所以绝对不能在ft_append内部释放
  • 旧字符串对应的内存,拷贝完成后没有任何指针会再访问,可以在ft_append内释放
  • 最终拼接完成的字符串,在main函数使用完毕后再释放即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 07:24:07