内存泄漏在c++中常见于手动管理内存,主要由四种模式引发。1. 忘记释放内存:如new后未delete,解决方法是使用智能指针或raii;2. 指针重赋值未释放原内存:应在赋值前释放或用智能指针自动处理;3. 容器存储裸指针未清理:应改用智能指针容器或编写清理函数;4. 异常路径跳过释放:应使用raii或智能指针确保异常安全。现代c++推荐智能指针和标准库容器以避免这些问题。

内存泄漏在C++中是一个常见但容易被忽视的问题,尤其是在手动管理内存的项目中。它会导致程序运行时间越长占用内存越多,最终可能引发崩溃或性能下降。下面通过几种常见的泄漏模式,结合实际案例来分析原因和应对方法。

1. 忘记 delete
已分配的内存
这是最直接的一种泄漏方式。当你使用
new或
new[]分配内存后,如果没有对应的
delete或
delete[],这块内存就无法释放。

例子:
立即学习“C++免费学习笔记(深入)”;
void exampleLeak() {
int* data = new int[100];
// 使用data...
// 忘记 delete[] data;
}每次调用这个函数都会泄露400字节(假设int是4字节)。

解决方法:
- 尽量使用智能指针(如
std::unique_ptr
,std::shared_ptr
) - 如果必须手动管理内存,确保每个
new
都有匹配的delete
- 使用RAII(资源获取即初始化)技术封装资源管理
2. 指针重新赋值导致的“悬空”内存
当一个指向动态内存的指针被重新赋值而没有先释放原内存时,就会造成泄漏。
例子:
立即学习“C++免费学习笔记(深入)”;
void leakAfterAssign() {
char* buffer = new char[256];
buffer = new char[512]; // 原来的256字节内存未释放
delete[] buffer;
}第一块内存没被释放就被覆盖了。
解决方法:
- 在重新赋值前先释放原有内存
- 或者一开始就使用智能指针自动处理
- 可以考虑封装成类,在析构函数中统一释放
3. 容器中存储原始指针导致的泄漏
很多新手会把裸指针存入
std::vector、
std::list等容器中,但如果忘记在容器销毁前手动释放这些指针指向的内存,就会泄漏。
例子:
立即学习“C++免费学习笔记(深入)”;
void containerLeak() {
std::vector<int*> vec;
for (int i = 0; i < 10; ++i) {
vec.push_back(new int(i));
}
// 忘记逐个 delete vec[i]
}循环创建了10块内存,但都没释放。
解决方法:
- 使用
std::vector<std::unique_ptr<int>>
替代裸指针 - 如果必须用裸指针,在容器销毁前遍历并删除每个元素
- 写清理函数集中处理释放逻辑,避免遗漏
4. 异常安全问题引起的泄漏
在抛出异常的情况下,如果代码路径跳过了
delete,也可能造成泄漏。比如:
void leakOnException() {
Resource* res = new Resource();
doSomethingThatMightThrow(); // 抛异常
delete res; // 这行不会执行
}解决方法:
- 使用 RAII 资源管理类(构造获取,析构释放)
- 或使用智能指针,这样即使异常抛出也能正确释放
- 减少裸指针的使用,从根本上避免这类问题
基本上就这些常见情况。虽然现代C++推荐使用智能指针和标准库容器来规避这些问题,但在遗留代码或性能敏感场景下,还是需要特别注意这些细节。










