C语言全局与局部指针变量的赋值操作差异原理疑问
核心认知修正
你对局部指针的用法理解本身存在错误,int *test; *test = value;属于典型的未定义行为(Undefined Behavior, UB),不存在「局部指针可以直接解引用赋值、全局指针不行」的规则差异,两者的底层要求完全一致:任何指针在解引用操作之前,必须先指向一块合法的、当前进程可访问的内存地址。
两类指针的表现差异底层原因
你观察到的现象本质是全局变量和局部变量的默认初始化规则不同:
- 全局存储周期的变量(包括你的全局指针
size)如果没有显式初始化,C语言标准规定会被默认初始化为0值,对应指针类型就是NULL(空指针,指向内存地址0)。操作系统对地址0做了访问保护,直接解引用空指针会触发非法内存访问,程序直接崩溃。 - 自动存储周期的局部变量(包括你的局部指针
test)没有显式初始化时,其值是栈内存上残留的随机垃圾值。这个随机值有可能碰巧指向了一块当前进程拥有写权限的内存区域,所以你执行*test = value的时候没有立刻崩溃,但这完全是运行时的巧合,本质还是非法操作,随时可能出现程序崩溃、数据污染、逻辑异常等问题。
指针的标准使用逻辑
不管是全局指针还是局部指针,使用前都必须先完成合法地址赋值,常见的两种合法方式:
- 指向已存在的同类型变量地址:即你代码中
size = &value的写法,将栈上变量value的合法地址赋值给指针后再解引用操作 - 申请动态堆内存:比如
int *test = malloc(sizeof(int));,申请到堆上的合法内存后再解引用赋值,使用完毕后需要调用free(test)释放内存,避免内存泄漏。
你的示例代码存在的问题
你贴出的测试代码包含两处典型的未定义行为:
- 局部指针
test未初始化就直接解引用赋值 - 未校验入参数量
argc就直接访问argv[1],如果运行程序时没有传入参数,会直接出现argv数组越界访问
内容的提问来源于stack exchange,提问作者Jay
相关产品推荐
相关产品推荐

