0

0

C++如何检测内存泄漏?(Valgrind与AddressSanitizer)

冰火之心

冰火之心

发布时间:2026-02-26 08:51:34

|

457人浏览过

|

来源于php中文网

原创

valgrind仅支持linux(部分bsd),需动态链接、禁用优化(-o0)、保留调试符号(-g);asan需编译链接均加-fsanitize=address并设asan_options;二者不可共存,应分阶段使用。

c++如何检测内存泄漏?(valgrind与addresssanitizer)

Valgrind 在 Linux 上跑不起来?先确认这三件事

Valgrind 本身不支持 macOS 和 Windows,只在 Linux(或部分 BSD)上可用,而且要求程序是动态链接的。静态链接的二进制、用了 __attribute__((constructor)) 过多的初始化逻辑、或者启用了某些内核级防护(如 ptrace 被禁用),都会导致 valgrind 启动失败或报 Illegal instruction

  • 检查是否在 Ubuntu/Debian 系统上安装了完整版:sudo apt install valgrind(别只装 valgrind-dbg
  • 编译时务必关闭优化(-O0),并保留调试符号(-g),否则行号和函数名全丢失
  • 避免用 std::thread + fork() 混用——Valgrind 对 fork 后的子进程跟踪不稳定,容易漏报

AddressSanitizer 报 heap-use-after-free 却找不到源头?

ASan 默认只显示崩溃点,不追溯分配位置。想定位原始 mallocnew 行,必须加运行时标志,而且得在编译时就埋好钩子。

  • 编译加 -fsanitize=address -g,链接也得带 -fsanitize=address(CMake 中要设 CMAKE_CXX_FLAGSCMAKE_EXE_LINKER_FLAGS
  • 运行前设环境变量:ASAN_OPTIONS=detect_stack_use_after_return=true:abort_on_error=true
  • 如果用的是 C++17 的 std::pmr::memory_resource 或自定义分配器,ASan 默认不拦截——得手动调用 __asan_poison_memory_region__asan_unpoison_memory_region

为什么 Valgrind 说没泄漏,但 RSS 内存持续上涨?

Valgrind 只检测堆内存(malloc/new 分配的),对 mmap/mprotect 分配的大块内存、线程栈、共享库数据段、甚至 std::string 的 SSO 缓冲区都不管。RSS 上涨 ≠ 堆泄漏。

SONIFY.io
SONIFY.io

设计和开发音频优先的产品和数据驱动的解决方案

下载
  • pmap -x <pid></pid> 查看各内存段大小,重点关注 [anon]stack
  • 怀疑线程泄漏?查 /proc/<pid>/status</pid> 里的 Threads: 字段,再结合 ps -T -p <pid></pid>
  • std::unordered_map 插入大量元素后不 shrink,会持有远超实际需要的 bucket 数组——这不是泄漏,但 Valgrind 不提醒你

ASan 和 Valgrind 能不能一起用?

不能。二者都靠插桩或二进制重写拦截内存操作,同时启用会冲突,轻则报错退出,重则触发未定义行为。选一个就行:开发阶段用 ASan(快、报错准),发布前回归用 Valgrind(覆盖更全,能发现 ASan 漏掉的未初始化读)。

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

  • ASan 编译产物体积大、运行慢 2–3 倍,但能在几秒内复现问题
  • Valgrind 运行慢 10–50 倍,且对多线程程序的误报率略高(比如条件变量唤醒顺序被重排)
  • CI 流水线里建议优先跑 ASan,Valgrind 留给 nightly 手动触发

真正难搞的是跨模块内存管理——比如 A 库用 new 分配、B 库用 free 释放,ASan 和 Valgrind 都可能沉默。这种得靠统一 allocator + 静态分析工具辅助。

热门AI工具

更多
DeepSeek
DeepSeek

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

豆包大模型
豆包大模型

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

通义千问
通义千问

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

腾讯元宝
腾讯元宝

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

文心一言
文心一言

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

讯飞写作
讯飞写作

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

即梦AI
即梦AI

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

ChatGPT
ChatGPT

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

相关专题

更多
string转int
string转int

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

850

2023.08.02

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

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

425

2023.07.18

堆和栈区别
堆和栈区别

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

597

2023.08.10

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

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

425

2023.07.18

堆和栈区别
堆和栈区别

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

597

2023.08.10

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

721

2023.08.10

Python 多线程与异步编程实战
Python 多线程与异步编程实战

本专题系统讲解 Python 多线程与异步编程的核心概念与实战技巧,包括 threading 模块基础、线程同步机制、GIL 原理、asyncio 异步任务管理、协程与事件循环、任务调度与异常处理。通过实战示例,帮助学习者掌握 如何构建高性能、多任务并发的 Python 应用。

371

2025.12.24

java多线程相关教程合集
java多线程相关教程合集

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

27

2026.01.21

batoto漫画官网入口与网页版访问指南
batoto漫画官网入口与网页版访问指南

本专题系统整理batoto漫画官方网站最新可用入口,涵盖最新官网地址、网页版登录页面及防走失访问方式说明,帮助用户快速找到batoto漫画官方平台,稳定在线阅读各类漫画内容。

331

2026.02.25

热门下载

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

精品课程

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

共94课时 | 10.2万人学习

C 教程
C 教程

共75课时 | 5万人学习

C++教程
C++教程

共115课时 | 19.4万人学习

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

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