0

0

c++中如何检测内存泄漏_c++内存泄漏排查工具与方法

裘德小鎮的故事

裘德小鎮的故事

发布时间:2026-01-06 16:39:10

|

950人浏览过

|

来源于php中文网

原创

_CrtDumpMemoryLeaks() 不需手动调用,启用 _CRTDBG_LEAK_CHECK_DF 后 CRT 会在 exit 前自动触发检测;需在 main 首行设 _CrtSetDbgFlag,Debug 模式链接 MTd/MDd,并定义 _CRTDBG_MAP_ALLOC 和 new 宏以获取文件行号。

c++中如何检测内存泄漏_c++内存泄漏排查工具与方法

_CrtDumpMemoryLeaks() 在程序退出时自动检测泄漏

Windows 下 Visual Studio 自带的 CRT 调试堆能捕获未释放的堆内存,前提是启用调试堆并正确配置。它不依赖外部工具,适合快速验证单次运行是否存在泄漏。

  • 必须在程序最开头(main() 第一行)调用 _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
  • 确保编译为 Debug 模式,且链接的是多线程调试版 CRT(如 MTdMDd
  • 不要手动调用 _CrtDumpMemoryLeaks() —— 设置了 _CRTDBG_LEAK_CHECK_DF 后,CRT 会在 exit() 前自动触发,此时调用信息才完整
  • 泄漏报告中显示的文件名和行号,依赖于在包含 stdlib.h 前定义 _CRTDBG_MAP_ALLOC,并使用 #define new new(_NORMAL_BLOCK, __FILE__, __LINE__)

AddressSanitizer(ASan)跨平台抓运行时泄漏

Clang 和 GCC 都支持 AddressSanitizer,它不仅能报内存泄漏,还能发现越界读写、UAF 等问题,且无需修改代码,只需编译选项开启。

  • 编译命令示例:
    g++ -g -O1 -fsanitize=address -fno-omit-frame-pointer leak.cpp -o leak
  • 运行后若存在泄漏,会输出类似:
    =================================================================
    ==12345==ERROR: LeakSanitizer: detected memory leaks
    Direct leak of 8 byte(s) in 1 object(s) allocated from:
        #0 0x7f... in operator new(unsigned long) (libclang_rt.asan.so)
        #1 0x56... in main leak.cpp:5
  • 注意:默认只检测“direct leak”,即无任何指针指向的内存;若想查“indirect leak”(例如对象 A 持有 B,B 泄漏但 A 还活着),需额外加环境变量LSAN_OPTIONS=detect_leaks=2
  • ASan 会显著拖慢运行速度、增大内存占用,**不适合压测或高频循环场景**,仅用于开发期排查

为什么 valgrind --leak-check=fullmacOS 上跑不了

valgrind 官方长期不支持 macOS(尤其是 10.12+),主因是系统内核机制(KASLR、AMFI、SIP)与 valgrind 的二进制插桩原理冲突。你看到的 Unsupported architecture 或直接崩溃不是配置问题,而是根本不可用。

笔墨写作
笔墨写作

一款专注于各类公文写作的AI写作平台

下载
  • macOS 替代方案只有两个可靠选择:AddressSanitizer(推荐)或 Xcode 自带的 Leaks 工具(需 Instruments 图形界面 + malloc stack logging 开启)
  • 如果坚持用 valgrind,唯一可行路径是用 Linux 虚拟机或 Docker 容器复现问题,**不能指望在 macOS 终端里编译出可用结果**
  • 注意:Instruments 的 Leaks 检测逻辑不同——它基于 malloc 日志回溯引用链,对 C++ 对象生命周期推断较弱,容易漏掉 RAII 外的裸指针泄漏

自定义 new/delete 运算符做轻量级泄漏统计

当项目不允许引入 ASan、又需在 Release 模式下长期监控时,可全局重载分配器,记录地址、大小、调用位置,退出时遍历未匹配的 delete

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

  • 核心是重载全局 ::operator new::operator delete,用 std::unordered_map 存活块(CallSite__FILE____LINE__size
  • 必须处理 nothrow 版本、数组版本(operator new[])、对齐版本(C++17 operator new(size_t, std::align_val_t)),否则部分分配会绕过统计
  • 多线程下需加锁(如 std::mutex),但锁本身可能引发死锁(比如在构造函数里 new 导致递归加锁),更安全的做法是用 std::atomic_flag 自旋或 TLS 存储待注册项
  • 该方法无法捕获 malloc/freeVirtualAlloc 等非 new 分配,也不能反映对象语义泄漏(比如智能指针循环引用)
实际排查时,多数人卡在“以为泄漏存在,其实是 ASan 报了间接泄漏但没开 detect_leaks=2”,或者在 macOS 上花半天配 valgrind 却不知道它早就弃疗了。真正有效的起点永远是:先确认泄漏是否真实存在(用 ASan 或 CRT),再决定要不要深入到自定义分配器级别。

相关专题

更多
typedef和define区别
typedef和define区别

typedef和define区别在类型检查、作用范围、可读性、错误处理和内存占用等。本专题为大家提供typedef和define相关的文章、下载、课程内容,供大家免费下载体验。

107

2023.09.26

define的用法
define的用法

define用法:1、定义常量;2、定义函数宏:3、定义条件编译;4、定义多行宏。更多关于define的用法的内容,大家可以阅读本专题下的文章。

321

2023.10.11

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1462

2023.10.24

Go语言中的运算符有哪些
Go语言中的运算符有哪些

Go语言中的运算符有:1、加法运算符;2、减法运算符;3、乘法运算符;4、除法运算符;5、取余运算符;6、比较运算符;7、位运算符;8、按位与运算符;9、按位或运算符;10、按位异或运算符等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

227

2024.02.23

php三元运算符用法
php三元运算符用法

本专题整合了php三元运算符相关教程,阅读专题下面的文章了解更多详细内容。

85

2025.10.17

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

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

380

2023.07.18

堆和栈区别
堆和栈区别

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

567

2023.08.10

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

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

380

2023.07.18

C++ 高性能计算与并行编程
C++ 高性能计算与并行编程

本专题专注于 C++ 在高性能计算(HPC)与并行编程中的应用,涵盖多线程、并发数据处理、OpenMP、MPI、GPU加速等技术。通过实际案例,帮助开发者掌握 如何利用 C++ 进行大规模数据计算和并行处理,提高程序的执行效率,适应高性能计算与数据密集型应用场景。

5

2026.01.08

热门下载

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

精品课程

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

共48课时 | 6.8万人学习

Git 教程
Git 教程

共21课时 | 2.5万人学习

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

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