温馨提示×

linux c++为什么内存泄漏

小樊
37
2026-09-26 07:58:21
栏目: 编程语言

在 Linux 下用 C++ 出现内存泄漏(memory leak),本质原因只有一个:

申请了内存(或其他资源),但程序结束前没有释放,并且失去了释放它的能力(指针丢失)。

下面从常见原因、Linux 特有因素、示例、排查方法几个角度说明。


一、C++ 内存泄漏最常见原因

1️⃣ new / delete 不匹配

int* p = new int[10];
// 错误
delete p;     // 应该是 delete[] p;

int* q = new int;
delete[] q;   // 未定义行为,可能泄漏

✅ 规则:

  • new ↔ delete
  • new[] ↔ delete[]

2️⃣ 忘记 delete

void foo() {
    int* p = new int(10);
    // 没有 delete p;
}

函数退出后:

  • p 被销毁
  • 堆内存仍然存在 → 泄漏

3️⃣ 异常导致 delete 没执行

void foo() {
    int* p = new int;
    throw 1;
    delete p; // 永远不会执行
}

✅ 正确方式:用智能指针

std::unique_ptr<int> p = std::make_unique<int>();

4️⃣ 指针被覆盖(早期内存丢失)

int* p = new int;
p = new int; // 第一块内存泄漏

5️⃣ 循环 / 容器中的泄漏

std::vector<int*> v;
v.push_back(new int);
// 程序退出前没 delete

6️⃣ 类里 new,但析构函数没 delete

class A {
    int* p;
public:
    A() { p = new int; }
    ~A() {} // 没 delete p;
};

✅ 正确:

~A() { delete p; }

或更推荐:

std::unique_ptr<int> p;

二、Linux 下“看起来像泄漏”的情况

1️⃣ glibc 内存不会立刻还给系统

Linux 使用:

  • brk
  • mmap

即使你 delete:

  • 内存可能仍被进程占用
  • top / ps 看 RSS 没下降

✅ 这是正常现象,不是泄漏


2️⃣ 内存碎片

频繁 new/delete 小块内存:

  • 无法合并
  • RSS 居高不下

3️⃣ 共享库 / STL 缓存

  • std::string
  • std::vector
  • pthread

可能缓存内存,不明显释放


三、Linux 下如何确认是不是真泄漏

✅ 1. Valgrind(最权威)

valgrind --leak-check=full ./your_program

输出示例:

definitely lost: 40 bytes

✅ 2. AddressSanitizer(推荐)

g++ -fsanitize=address -g main.cpp
./a.out

✅ 3. 观察 /proc/<pid>/status

cat /proc/$(pidof your_program)/status | grep VmRSS

四、C++ 防止内存泄漏的最佳实践(Linux)

✅ 90% 泄漏可避免:

  • 不用裸 new
  • 使用:
    • std::unique_ptr
    • std::shared_ptr
    • std::vector
    • std::string

✅ RAII 原则:

资源获取即初始化,析构即释放


五、一句话总结

Linux C++ 内存泄漏,不是 Linux 的问题,而是“你申请了内存但没释放,或释放不了”。

如果你愿意,可以把具体代码或 Valgrind 输出贴出来,我可以直接帮你定位是哪一行泄漏。

0 踩