0

0

C++中的内存泄漏(Memory Leak)是什么?(如何有效检测和修复)

穿越時空

穿越時空

发布时间:2026-02-16 14:28:02

|

545人浏览过

|

来源于php中文网

原创

内存泄漏是动态分配内存后未释放,导致运行时内存持续增长并可能被oom杀死;c++中需严格配对new/delete、malloc/free,避免错配或遗漏;推荐用raii智能指针(unique_ptr/shared_ptr/weak_ptr)和工具(valgrind、asan)检测与预防。

c++中的内存泄漏(memory leak)是什么?(如何有效检测和修复)

内存泄漏就是 new 了没 delete,或 malloc 了没 free

它不是程序崩溃那一刻才出问题,而是像漏水的水管——每次运行都悄悄多占一点内存,跑得越久越卡,最终可能被系统 OOM 杀掉。C++ 没垃圾回收,newnew[]malloc 这些调用后,必须有且仅有一次对应的 deletedelete[]free;漏掉、重复、错配(比如 newfree),都算泄漏。

常见错误现象:

  • valgrinddefinitely lostpossibly lost
  • 程序长时间运行后 RSS 内存持续上涨,tophtop 里看 RES 列不停变大
  • std::shared_ptr 却在循环引用里忘了 std::weak_ptr 断环

用 valgrind 快速定位泄漏点(Linux/macOS)

valgrind 是目前最靠谱的动态检测工具,不用改代码,但只支持 x86/x64,macOS 12+ 需用 valgrind --tool=memcheck --leak-check=full --show-leak-kinds=all ./your_program(注意:Apple Silicon 上原生不支持,得用 Rosetta 启动)。

实操建议:

立即学习C++免费学习笔记(深入)”;

360智图
360智图

AI驱动的图片版权查询平台

下载
  • 编译时加 -g,否则 valgrind 只能显示汇编地址,看不到函数名和行号
  • 避免优化等级过高(比如 -O2),-O0 -g 最稳妥
  • 关注输出里 at 0x...: your_function (file.cpp:42) 这类带源码位置的行,优先修这些
  • 如果看到 still reachable,多数是全局缓存或日志缓冲区,不一定算 bug,但得人工确认是否预期

RAII 是防泄漏的底层逻辑,不是语法糖

手动配对 new/delete 在复杂控制流(比如中间有 return、异常抛出)里极易出错。RAII 的核心是“资源即对象”:把内存绑定到栈对象生命周期上,靠析构函数自动释放。

该用什么,怎么选:

  • 单个对象 → 用 std::unique_ptrauto p = std::make_unique<int>(42);</int>,离开作用域自动 delete
  • 需要共享所有权 → 用 std::shared_ptr,但警惕循环引用:std::shared_ptr 持有对方,std::weak_ptr 观察对方
  • 数组 → 必须用 std::unique_ptr<t></t>std::vectorstd::unique_ptr<int></int>new int[10] 会只调 delete 不调 delete[],UB
  • 别再裸写 new —— 除非你在写底层容器或性能敏感的内联热路径,且能 100% 控制所有出口

ASan(AddressSanitizer)比 valgrind 更快,但只能捕获部分泄漏

ASan 是编译器内置检测器(GCC/Clang 支持),启动快、开销小,但它默认只报内存错误(越界、UAF),泄漏检测需额外开启:-fsanitize=address,leak,且只对 malloc/new 系列有效,不覆盖 mmap 或自定义分配器。

使用场景和限制:

  • 开发机日常编译加 -fsanitize=address,leak -g,跑单元测试能快速发现新引入的泄漏
  • ASan 报的 LeakSanitizer: detected memory leaks 会给出调用栈,但不如 valgrind 全面(比如不报 still reachable
  • Windows 下用 Application Verifier + Dr. Memory 替代,但体验和精度打折扣
  • CI 流水线里建议 valgrind 和 ASan 都跑,互补盲区

真正难的不是找到泄漏,而是判断“这块内存该不该释放”——比如一个全局 std::map 缓存,生命周期贯穿整个进程,valgrind 会报它 leaked,但其实是设计如此。这时候得翻文档、问作者、看初始化逻辑,而不是无脑加 delete

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

750

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

568

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

234

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

209

2025.08.29

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

418

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

591

2023.08.10

golang map内存释放
golang map内存释放

本专题整合了golang map内存相关教程,阅读专题下面的文章了解更多相关内容。

75

2025.09.05

golang map相关教程
golang map相关教程

本专题整合了golang map相关教程,阅读专题下面的文章了解更多详细内容。

36

2025.11.16

pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

145

2026.02.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 9.6万人学习

C 教程
C 教程

共75课时 | 4.8万人学习

C++教程
C++教程

共115课时 | 18万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号