C 悬空指针

代码核心

  1. fun函数执行完毕函数栈帧销毁:局部变量a的内存空间被回收,这块栈内存已经不属于a了
  2. 指针p保存的仍然是原来a的地址,但是地址指向的内存已经失效 → p就是悬空指针
  3. 读取*p属于未定义行为 UB,结果不确定

为什么第一次输出 10,第二次变成乱码

● 调用fun结束,栈帧销毁,只是标记这块内存可以被复用,不会立刻清零

● 第一次printf("%d\n", *p);:此时栈内存还没被别的指令覆盖,数据10还留在原地,所以碰巧打印 10

● 执行完第一个printf,printf函数调用会复用这块栈空间,把栈内存覆盖

● 第二个printf("%d\n", *p);:原来存放 10 的内存已经被改写,读出随机垃圾值 -858993460

重点:不是一定会先对后错! 未定义行为,不同编译器、不同编译选项、不同系统,结果完全不一样,有可能两次都是 10,也有可能直接程序崩溃

悬空指针定义

指针保存了一个合法地址,但这个地址对应的内存已经被释放 / 销毁,这个指针就叫悬空指针

区别:

● NULL 指针:指针 = 0,指向空,没有指向任何内存

● 悬空指针:指针有地址值,但指向的内存已经失效

产生悬空指针常见场景

  1. 函数返回局部变量的地址(当前这个例子)✅
  2. free释放堆内存之后,没有把指针置 NULL
c 复制代码
int *p = malloc(sizeof(int));
free(p);  // 内存释放
// p现在就是悬空指针!p里面地址没变,但内存已经还给系统
  1. 数组 / 内存空间生命周期结束,指针还保留旧地址

怎么避免悬空指针

  1. ❌ 不要返回栈上局部变量的地址;想返回数据,可以传指针参数、返回堆 malloc 内存(记得 free)、static 静态变量(static 变量不在栈)
  2. free之后,手动把指针赋值为NULL
c 复制代码
free(p);
p = NULL;
  1. 保证指针生命周期 ≤ 指向内存的生命周期

补充总结

项目 说明
局部变量 a 在 fun 函数栈帧,函数 return 后栈帧销毁,内存回收
p 指针 保存 a 原来的地址,内存失效 → 悬空指针
*p 解引用 C 标准:未定义行为,结果随机,程序可能崩溃
现象原因 栈不会自动清零,后续函数调用会覆盖栈内存
相关推荐
Akamai中国1 小时前
PHP 爆出两大高风险漏洞!Akamai 即时部署防护机制
开发语言·人工智能·云计算·云服务
weixin_417396831 小时前
酒店弱电怎么验收?四个阶段与逐项检查清单
开发语言·前端·php·综合布线·弱电
H.莓飛11 小时前
【数据结构】排序_OJ题(一):计数、桶与排序后的处理
java·开发语言·数据结构
wangchunyu11412 小时前
JAVA AQS与Lock实现原理(含CAS)
java·开发语言·word
爱喝水的鱼丶13 小时前
SAP-ABAP:ECC→S/4HANA ABAP 迁移升级指南——程序改造、语法兼容与性能优化 导语
运维·开发语言·性能优化·sap·abap·经验交流·开发交流
小灰灰搞电子13 小时前
Rust+Slint 实现FTP客户端调试助手源码分享
开发语言·后端·rust
外收内放13 小时前
面向对象高级(实战案例)
开发语言·python·学习
·present·14 小时前
CSAPP(lecture 4_01)
c语言·c++
fanruitian14 小时前
python else用法
开发语言·python