C 内存泄漏ASAN 工具 超详细使用教程AddressSanitizerASAN是 C 排查内存泄漏的工具比 Valgrind 快 5~10 倍GCC/Clang/VS 全都自带不用额外安装直接编译就能用。它能精准检测内存泄漏malloc/new 没 free/delete堆溢出、栈溢出野指针、重复释放使用已释放内存一、1 分钟快速上手直接复制用1. 编译命令GCC / Clang编译时加一个参数# 必加-fsanitizeaddressg-g-fsanitizeaddress main.cpp-otest运行程序./test程序退出时ASAN 会自动打印泄漏位置 代码行号。二、完整示例检测出泄漏测试代码故意写内存泄漏#includeiostreamusingnamespacestd;voidtest_leak(){// 堆上申请内存没有 delete → 泄漏int*arrnewint[100];}intmain(){test_leak();return0;}编译 运行g-g-fsanitizeaddress main.cpp-otest./testASAN 直接输出泄漏结果ERROR: LeakSanitizer: detected memory leaks Direct leak of 400 byte(s) in 1 object(s) allocated from: #0 operator new[](unsigned long) (libasan.so...) #1 test_leak() main.cpp:6 #2 main main.cpp:10直接告诉你哪一行泄漏main.cpp 第 6 行泄漏大小400 字节哪个函数test_leak()三、ASAN 常用编译参数必记1. 基础必用检测泄漏越界g-g-fsanitizeaddress test.cpp-otest-g保留调试信息必须加否则不显示行号-fsanitizeaddress开启 ASAN2. 只检测内存泄漏更快# 只检查泄漏不检查越界/野指针g-g-fsanitizeleak test.cpp-otest3. 关闭泄漏检查只查越界exportASAN_OPTIONSdetect_leaks0./test四、Windows VS 使用 ASANVS 2019 及以上原生支持不用装插件右键项目 →属性C/C → 常规 → 启用地址消毒剂→ 选择是 (/fsanitizeaddress)重新编译运行输出窗口直接显示泄漏行号五、ASAN 泄漏报告怎么看报告结构非常清晰ERROR: LeakSanitizer: detected memory leaks Direct leak of 400 byte(s) in 1 object(s) allocated from: #0 operator new[](unsigned long) #1 test_leak() main.cpp:6 -- 泄漏代码行 #2 main main.cpp:10重点看Direct leak直接泄漏byte(s)泄漏大小main.cpp:6精确到行号调用栈谁申请了没释放六、C 最常见的泄漏场景ASAN 一键查出1. new 没 delete / new[] 没 delete[]int*pnewint;// 没 delete p; → 泄漏2. 容器/指针忘记释放vectorint*vec;vec.push_back(newint);// 程序结束没遍历 delete → 泄漏3. 类中指针没在析构函数释放classA{int*p;public:A(){pnewint;}// ~A() { delete p; } 析构函数忘写 → 泄漏};4. 函数内申请内存没有返回也没有释放voidfunc(){char*bufnewchar[1024];// 没释放直接退出 → 泄漏}七、注意事项ASAN 会增加内存占用约 2x性能下降约 2 倍→ 只用于测试/调试不要上线生产环境。必须加-g编译才能显示行号。多线程程序也能正常检测。有些库如第三方静态库没开 ASAN可能出现误报可用exportASAN_OPTIONSdetect_leaks0总结C 排查内存泄漏首选 ASAN自带能准确定位到行号。编译只需要加-g -fsanitizeaddress。运行程序退出后自动打印泄漏报告。能查泄漏、越界、野指针、重复释放。你只要把你的代码用这个参数重新编译运行就能立刻看到所有内存泄漏位置。