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

返回malloc分配的指针后是否需调用free?复用地址会有问题吗?

问题解答

代码里的两个明显问题

  • return后的free(t)永远不会执行:函数执行到return t就直接返回了,后续代码完全不会运行,这块堆内存会处于内存泄漏状态——分配后从未被释放。
  • 数组越界写入:你分配的内存大小是length(a)+length(b)+1,合法索引范围是0到length(a)+length(b)(数组从0开始计数),但你写了t[length(a)+length(b)+1] = '\0';,这已经超出分配的内存边界,会触发未定义行为,可能破坏堆结构或其他数据。

核心疑问解答

1. 已释放的内存会不会被malloc复用?

会的。内存分配器会把释放的内存加入空闲内存池,后续调用malloc时,如果有匹配大小的空闲块,会优先复用这些内存,而非向操作系统申请新内存。

2. 若z指向已释放的地址,后续malloc复用该地址会引发问题吗?

肯定会。调用free(z)后,z就成了野指针——指向的内存不再属于当前程序的有效内存范围。如果后续malloc复用这个地址:

  • 再通过z读写这块内存,会篡改新分配变量的数据,导致逻辑混乱甚至程序崩溃;
  • 新分配的变量会覆盖这块内存的数据,若你还以为z指向原来的字符串,读取到的会是错误内容。

3. 返回malloc分配的指针后是否需要调用free()?

必须要。malloc分配的堆内存不会像栈变量一样随函数结束自动释放,conc函数返回指针后,内存的释放责任就转移给了调用者——也就是main函数里,你需要在使用完z之后调用free(z);,否则内存会一直被占用,直到程序结束才会被操作系统回收。

修正后的代码示例

#include <string.h>
#include <stdlib.h>
#include <stdio.h>

char *conc(char *a, char *b){
    size_t len_a = strlen(a);
    size_t len_b = strlen(b);
    // 分配内存,同时检查malloc是否成功
    char *t = malloc(len_a + len_b + 1);
    if (t == NULL) {
        return NULL;
    }
    // 拷贝字符串a
    for(size_t i = 0; i < len_a; i++){
        t[i] = a[i];
    }
    // 拷贝字符串b
    for(size_t j = 0; j < len_b; j++){
        t[len_a + j] = b[j];
    }
    // 正确设置字符串终止符
    t[len_a + len_b] = '\0';
    return t;
}

int main (void){
    char *x = "he";
    char *y = "llo dude";
    char *z = conc(x, y);
    if (z != NULL) {
        // 使用z
        printf("%s\n", z);
        // 使用完毕释放内存
        free(z);
        z = NULL; // 置空避免野指针
    }
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 18:52:02