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

C语言向函数传入NULL指针解引用赋值触发段错误原因问询

NULL指针传参触发段错误的原因

核心逻辑基于两个C语言的基础规则:

  • C语言所有函数参数均为值传递,传入指针时,函数内部拿到的是指针值的拷贝,而非外部原指针变量本身;修改形参指针的指向,不会影响外部原指针的值。
  • NULL是不指向任何合法可访问用户态内存的特殊地址值,对NULL指针做解引用读写属于未定义行为,在通用操作系统上会直接触发内存访问异常,抛出段错误。

可正常运行代码的执行逻辑

  • 第一份正常代码:main函数中的指针p直接指向栈上分配的字符变量v,对应的地址是合法可写的栈内存地址。p的值(即v的栈地址)被传入f函数后,f内部的形参p持有该地址的拷贝,解引用该地址写入字符'a',本质是直接修改栈上v的值,全程没有非法内存访问,因此可以正常输出a。
void f(char *p)
{
    *p = 'a';
}

int main()
{
    char v;
    char *p = &v;
    f(p);
    printf("%c", *p);
    // Output : a
    return 0;
}
  • 第二份正常代码:main函数中p初始值为NULL,但f函数内部没有直接解引用传入的NULL地址,而是先通过calloc申请了1字节合法的可写堆内存,将这块堆内存的地址赋值给f内部的形参p,再向该合法地址写入'a',最后把堆内存地址返回给main中的p。整个流程从未对NULL地址做解引用操作,所有写入都落在合法申请的内存上,因此可以正常输出a。
char *f(char *p)
{
    p = (char*)calloc(1, sizeof(char));
    *p = 'a';
    return p;
}

int main()
{
    char *p = NULL;
    p = f(p);
    printf("%c", *p);
    // Output : a
    return 0;
}

问题代码触发段错误的具体原因

两份问题代码的崩溃核心完全一致:传入f函数的指针值为NULL,函数内部没有为指针分配合法可访问的内存,就直接解引用指针做写入操作。

  • 问题代码1:main中将p初始化为NULL,将NULL值作为参数传入f函数,f内部直接执行*p = 'a',相当于向NULL对应的内存地址写入数据。通用操作系统中NULL通常对应地址0,这块区域是内核保留的受保护内存,用户态程序没有读写权限,CPU会直接触发内存访问异常,操作系统向进程发送SIGSEGV信号,最终抛出段错误。
void f(char *p)
{
    *p = 'a';
}

int main()
{
    char *p = NULL;
    f(p);
    printf("%c", *p);
    // Output : Segmentation fault (core dumped)
    return 0;
}
  • 问题代码2:崩溃逻辑和问题代码1完全一致,仅多了一步将形参p(值仍为NULL)返回给main的操作。崩溃实际发生在f内部执行*p = 'a'的环节,代码根本不会执行到返回和后续printf步骤。就算跳过写入环节的崩溃,返回给main的p还是NULL,后续printf中解引用*p同样会触发段错误。
char *f(char *p)
{
    *p = 'a';
    return p;
}

int main()
{
    char *p = NULL;
    p = f(p);
    printf("%c", *p);
    // Output : Segmentation fault (core dumped)
    return 0;
}

扩展:如果需要在函数内部为外部传入的NULL指针分配内存,不能只传一级指针,需要传入指针的地址(即二级指针),让函数可以直接修改外部原指针的值,参考写法:

void f(char **p)
{
    *p = (char*)calloc(1, sizeof(char));
    **p = 'a';
}

int main()
{
    char *p = NULL;
    f(&p);
    printf("%c", *p);
    free(p); // 堆内存使用后需要手动释放避免泄漏
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 07:57:08