悬空指针/野指针/空指针的区别与防范
请区分C++中的悬空指针(Dangling Pointer)、野指针(Uninitialized Pointer/Wild Pointer)和空指针(Null Pointer)的概念。它们各自如何产生?如何从编程实践上防范这三种指针问题?
回答
编译有声
1. 空指针(Null Pointer):值为nullptr/NULL的指针,不指向任何有效对象。
- 防范:解引用前检查
if(p != nullptr);C++11起用nullptr代替NULL
2. 悬空指针(Dangling Pointer):指向已经释放/销毁的内存。产生原因:
delete p后未置空:delete p; p = nullptr;- 栈对象销毁后指针保留:
int* p = &local_var;(离开作用域后p悬空) - 返回局部变量地址:
int* f() { int x; return &x; } - 容器迭代器失效后继续使用
- 防范:delete后置nullptr;优先用智能指针;避免返回栈地址
3. 野指针(Wild Pointer/未初始化指针):声明后未初始化就使用,指向随机内存地址。
- 防范:声明即初始化:
int* p = nullptr;;在成员初始化列表中初始化指针成员
危害评级:野指针>悬空指针>空指针
- 空指针解引用:段错误(SIGSEGV),可crash定位
- 悬空指针:可能被重用(use-after-free),导致数据损坏或安全漏洞
- 野指针:随机地址访问,最难诊断
最佳实践:
- 优先使用智能指针(unique_ptr/shared_ptr)代替裸指针
- 必用裸指针时,声明即初始化(nullptr)
- delete后置nullptr
- 使用AddressSanitizer/Valgrind检测
- C++17的
std::observer_ptr表达非拥有观察者意图