0 结论
空指针:是程序员主动设置的不指向任何对象的指针,用于初始化和安全判断。
野指针:是未初始化的指针,其值是随机的,行为完全不可预测,非常危险。
悬空指针:是指针指向的内存被释放后未置空导致的,它指向一个无效的地址,解引用会导致 use-after-free 错误。
避免:始终初始化指针、释放后立即置空、以及最重要的——使用 std::unique_ptr 和 std::shared_ptr 等智能指针来自动管理生命周期。RAII思想是永远的神!
1 空指针 (Null Pointer)
定义:明确被设置为 nullptr (C++11 及以上) 或 NULL (传统 C/C++) 的指针,表示它故意不指向任何有效的内存地址。
int *p1 = nullptr; // C++11 推荐方式
int *p2 = NULL; // 传统方式,通常是 0
int *p3 = 0; // 直接赋值为 0使用指针的注意事项:
在声明指针时立即初始化为
nullptr。指针在释放内存后,应立即置为
nullptr。使用前做判空检查。
*p1 = 10; // 危险!运行时错误!引用空指针会导致未定义行为 (Undefined Behavior),通常是程序崩溃(段错误)
if (p1 != nullptr) {
*p1 = 10; // 安全操作
}2 野指针 (Wild Pointer)
定义:指针未被初始化,其值是随机的、不确定的(垃圾值)。它可能指向内存中的任意一个地址。
int *wildPtr; // 未初始化,值是随机的
*wildPtr = 10; // 极度危险!可能破坏系统数据!对野指针进行写操作可能会覆盖随机内存地址的数据,导致程序崩溃、数据损坏,甚至系统崩溃,行为完全不可预测。
未初始化是编程中最低级的错误之一,记住永远初始化指针,在声明时就直接初始化。
int *ptr = nullptr; // 总是这样做
int *ptr = new int(10); // 或者直接指向有效内存3 悬空指针 (Dangling Pointer)
定义:指针曾经指向一个有效的内存地址,但该内存已被释放或销毁,而这个指针却没有被重置(例如,没有置为 nullptr)。它就像一个指向已回收房屋的门牌号,极其危险。
指向已释放的堆内存
int *ptr = new int(100); // 分配堆内存
delete ptr; // 释放内存
// 此时 ptr 变成悬空指针,但它仍然保存着之前的地址值
*ptr = 50; // 灾难性行为!未定义行为!指向已销毁的栈对象
int *danglingPtr;
{
int localVar = 42; // 栈变量
danglingPtr = &localVar;
} // 作用域结束,localVar 被销毁
// danglingPtr 现在是一个悬空指针,指向无效的栈内存
cout << *danglingPtr; // 未定义行为!use-after-free 漏洞的根源,代码可能偶尔正常运行,有时却崩溃,行为不可预测,因为释放后的内存可能被系统重新分配用于其他用途。
避免的方式:
指针在释放后立即置空:
delete ptr; ptr = nullptr;避免返回局部变量的地址。
使用智能指针(如
std::unique_ptr,std::shared_ptr)!这是最根本的解决方案。智能指针会在对象被销毁后自动管理指针状态,从而避免悬空指针。
评论区