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

为什么两段使用未初始化C指针的C代码一段报段错误一段可运行?

问题原因解释

核心前提

两段代码均存在严重的未定义行为,第二段代码所谓的“可以正常运行”只是特定环境下的偶然现象,不代表代码本身符合C语言规范,也不具备可移植性。

共同错误根源

两段代码都存在「未初始化指针解引用写入」的问题:

  • 局部非静态变量在C语言中不会被自动初始化,定义的int *p分配在函数栈帧上,存储的是栈内存中残留的随机垃圾值,即p指向完全随机的内存地址。
  • 执行*p = 10时,相当于向这个随机地址写入数据,操作后果完全不可预测,属于C语言标准明确规定的未定义行为。

运行表现差异的底层原因

差异本质是栈帧布局变化导致p的随机指向地址属性不同:

  • 第一段代码的main函数栈帧中仅存在int *p一个局部变量,栈上残留的垃圾值刚好让p指向了当前进程无访问权限的地址(比如系统预留的非法地址、只读内存段地址),写入操作触发操作系统的内存保护机制,直接抛出段错误。
  • 第二段代码新增了char c = 'c'的局部变量定义,编译器分配栈空间的结构、栈上残留的垃圾值内容都发生了变化,此时p存储的随机垃圾值刚好落在当前进程拥有写权限的内存区域(比如当前进程的栈空间、可写数据段区域),所以写入操作没有触发系统异常,表面看起来“正常运行”。但此时已经发生了非法内存写入,可能破坏进程自身的合法数据,后续运行依然存在崩溃、逻辑异常等不可预测的风险。

正确写法参考

必须先让p指向合法的可写内存,再进行解引用操作,示例:

#include <stdio.h>
int main()
{
    int num;
    int *p = &num; // 让p指向合法的int变量地址
    *p = 10;
    printf("%d", *p); // 输出10,运行完全稳定
    return 0;
}

或者使用堆内存:

#include <stdio.h>
#include <stdlib.h>
int main()
{
    int *p = malloc(sizeof(int)); // 申请堆内存
    if (p != NULL) {
        *p = 10;
        printf("%d", *p);
        free(p); // 记得释放内存
    }
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 17:39:03