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 标准:未定义行为,结果随机,程序可能崩溃
现象原因 栈不会自动清零,后续函数调用会覆盖栈内存
相关推荐
沐晓时光13 小时前
C语言入门,内存函数知识讲解
c语言·开发语言
Zwawa16 小时前
C语言函数指针与宏实战:从回调、表驱动菜单到X-Macro,讲透嵌入式代码解耦
c语言·单片机·嵌入式
David猪大卫19 小时前
【C++修炼】map 和 set 的使用
c语言·开发语言·数据结构·c++·经验分享·笔记·学习
HPtiger19 小时前
C++ 入门笔记:从 C 到 C++ 的核心过渡(命名空间、输入输出、缺省参数、重载、引用、内联)
c语言·c++·学习
fengci.20 小时前
CTF2MISC中等部分
开发语言·前端·学习
xys_67821 小时前
JavaEE通关手册:初识Java
java·开发语言
安妮细水长流1 天前
ad7124
c语言·单片机
ShineWinsu1 天前
对于Qt:QTableWidget常见属性以及QTableWidgetItem类的解析
开发语言·c++·qt·gui·客户端·表格·qtablewidget
曾令胜1 天前
云服务器被攻击后分析恶意脚本修复漏洞
网络安全·安全威胁分析
ShineWinsu1 天前
对于Qt:QListWidget常见属性以及QListWidgetItem类的解析
开发语言·c++·qt·客户端·列表·qlistwidget·qlistwidgetitem