野指针和内存泄漏是什么?
野指针和内存泄漏是 C/C++ 中两个非常常见且危险的内存管理问题,下面我们详细讲解:
🧨 1. 什么是野指针(Dangling Pointer)?
野指针是指向无效(已经释放或未初始化)内存区域的指针。
✅ 典型情况:
🧱 情况一:指针未初始化
int* p; // 未初始化,p 指向未知地址
*p = 10; // 💥 未定义行为,野指针!
🧱 情况二:指针指向的内存已被释放
int* p = new int(10);
delete p;
*p = 5; // 💥 野指针!释放后继续使用
🧱 情况三:返回局部变量地址
int* func() {int a = 10;return &a; // 💥 返回了局部变量地址,出函数后地址无效
}
⚠️ 后果:
-
访问野指针会导致:
- 崩溃(如段错误
Segmentation fault
) - 难以定位的 bug
- 数据破坏(写入非法内存)
- 崩溃(如段错误
🧹 2. 什么是内存泄漏(Memory Leak)?
内存泄漏是指:堆上分配的内存没有释放,导致程序运行中内存持续增长,最终可能导致系统资源耗尽。
✅ 典型例子:
🧱 忘记 delete
或 free
void func() {int* p = new int[100]; // 申请了 400 字节// 没有 delete[] p;// 💥 内存泄漏:程序离开后指针没释放,无法访问也无法回收
}
🧱 指针被覆盖,丢失引用
int* p = new int[50];
p = new int[100]; // 原来那 50 个 int 的内存地址丢了!
🔍 特点:
- 不会立即崩溃,但内存会越来越多
- 在服务端、长期运行程序中极其致命
- 通常需借助工具(如 Valgrind、ASan)检测
📌 野指针 vs 内存泄漏
项目 | 野指针 | 内存泄漏 |
---|---|---|
定义 | 指向非法/不可用内存的指针 | 分配的内存没有释放 |
后果 | 崩溃、未定义行为、破坏数据 | 内存占用不断上涨,可能撑爆系统 |
检测难度 | 中等(ASan 可查) | 较难(Valgrind 常用) |
处理方式 | 初始化指针,置空,RAII | 使用智能指针,手动 delete |
🛡️ 如何避免这两类问题?
✅ 避免野指针
- 所有指针都要初始化,初始值设为
nullptr
- delete 后立即置为
nullptr
- 不返回局部变量地址
- 使用智能指针(如
std::unique_ptr
、std::shared_ptr
)
✅ 避免内存泄漏
- 手动申请的内存要保证释放路径
- 使用智能指针管理资源(RAII)
- 用工具检测(Valgrind, AddressSanitizer)
✅ 总结一句话:
野指针 = 用了“坏掉”的指针;内存泄漏 = 忘了把申请的内存还回去。
两者都能造成严重后果,C++ 程序员必须养成良好的内存管理习惯。