迷途指针是悬空指针,编译通过但访问会引发未定义行为;根本原因是delete后未置nullptr,指针仍保留原地址却指向已释放内存。

迷途指针(Dangling Pointer)就是悬空指针——它不是语法错误,编译能过,运行可能暂时正常,但只要稍一访问,就大概率触发未定义行为(如崩溃、数据错乱、安全漏洞)。根本原因是:指针还“记得”地址,但那块内存早已不属于你。
delete 后没置 nullptr 就是典型悬空
很多人以为 delete ptr 后指针自动失效,其实它只是释放了内存,ptr 的值没变,仍指向原地址。下次用 *ptr 或 ptr->xxx,就是在读写已归还给系统的内存。
- 错误写法:
int* p = new int(42); delete p; cout → 未定义行为 - 正确习惯:
delete p; p = nullptr;,后续可用if (p)安全判断 - 注意:即使设为
nullptr,也不能恢复已释放的对象,只是让误用更容易被发现
返回局部变量地址导致的悬空更隐蔽
这类悬空不涉及 new/delete,但危害一样大——栈变量生命周期一结束,指针立刻失效。
- 典型错误:
int* f() { int x = 10; return &x; }→x函数退出即销毁,返回值是悬空指针 - 编译器通常会警告(如
address of local variable returned),但不是所有场景都报 - 不能靠“试运行没崩”来验证,这块栈内存可能暂时没被覆盖,但换编译选项、加优化、多线程后极易暴露
shared_ptr 不能完全防悬空,尤其混用原始指针时
智能指针解决的是“谁该释放内存”,但不解决“谁还在持有无效地址”。一旦从 shared_ptr 获取裸指针(如 get()),就重新踏入悬空风险区。
- 危险操作:
auto sp = make_shared<int>(100); int* raw = sp.get(); sp.reset(); cout → 悬空</int> -
weak_ptr是为此设计的:用lock()检查对象是否还活着,返回shared_ptr才安全访问 - 原则:裸指针生命周期必须严格短于其所指对象;否则,优先用引用或
shared_ptr传递所有权
悬空指针最难缠的地方在于:它不总立即出错。可能在测试环境一切正常,上线后某个特定内存布局下才崩溃——所以不能依赖“没报错=没问题”,而要从代码逻辑上杜绝裸指针脱离对象生命周期的绑定。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











