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

C语言传指针入函数分配内存后原指针仍为NULL问题求解

问题根源

C语言函数参数采用值传递规则:调用xf(p)时,传入的是外层p变量存储的数值(也就是初始的NULL),函数形参p是实参的独立拷贝。在xf内部给形参p赋值malloc返回的堆地址,修改的只是这份拷贝的值,完全不会影响外层pf函数里的原始p变量,因此外层p始终为NULL,后续解引用空指针就会触发段错误,同时xf内申请的堆内存没有被释放也没有被外层持有,还会造成内存泄漏。

可行解决方案

有两种标准实现方式可以满足统一内存分配的需求:

方案1:传入指针的地址(二级指针形式)

要在函数内修改外层的指针变量,需要传入该指针变量本身的内存地址,用二级指针作为形参接收,直接修改外层变量的值:

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

// 形参为二级指针,接收int*类型变量的地址
void xf(int **p) {
    *p = malloc(sizeof(int));
    printf("xf: %p\n", *p);
    **p = 123;
}

int *pf() {
    int *p = NULL;
    xf(&p); // 传入指针p的地址,而非p存储的值
    printf("pf: %p\n", p);
    return p;
}

int main()
{
    int *a = pf();
    printf("===%p %p===\n", NULL, a);
    printf("%d\n", *a);
    free(a); // 释放堆内存,避免泄漏
    return 0;
}

方案2:让内存分配函数直接返回分配好的指针

把内存分配函数的返回值设为对应指针类型,直接将malloc得到的堆地址返回给外层调用方接收:

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

// 直接返回分配完成的int类型指针
int* xf() {
    int *p = malloc(sizeof(int));
    printf("xf: %p\n", p);
    *p = 123;
    return p;
}

int *pf() {
    int *p = NULL;
    p = xf(); // 接收分配函数返回的指针地址
    printf("pf: %p\n", p);
    return p;
}

int main()
{
    int *a = pf();
    printf("===%p %p===\n", NULL, a);
    printf("%d\n", *a);
    free(a); // 释放堆内存,避免泄漏
    return 0;
}
额外注意事项
  • 所有通过malloc/calloc/realloc申请的堆内存,使用完后必须调用free()释放,否则会造成内存泄漏
  • 正式代码中需要检查malloc的返回值是否为NULL,处理内存分配失败的异常场景,避免空指针解引用问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 02:54:21