0

0

C++如何检测程序内存泄漏工具Valgrind用法_Linux下C++代码质量检查【工具】

裘德小鎮的故事

裘德小鎮的故事

发布时间:2026-02-07 15:05:03

|

412人浏览过

|

来源于php中文网

原创

Valgrind能检测C++ new/delete不匹配,需编译时加-g和-O0;它只跟踪堆内存调用配对,不解析异常或RAII,对智能指针循环引用和第三方库内存会误报,推荐日常用AddressSanitizer替代。

c++如何检测程序内存泄漏工具valgrind用法_linux下c++代码质量检查【工具】

Valgrind 能不能直接查 C++ new/delete 不匹配

能,但需要编译时加 -g 且避免优化(-O0),否则行号丢失、调用截断。Valgrind 不解析 C++ 异常栈或 RAII 自动释放逻辑,它只跟踪堆内存的 malloc/free、new/delete 调用配对情况。如果对象在构造函数里 new 了内存但析构没 delete,Valgrind 会报“still reachable”或“definitely lost”,具体取决于指针是否还在作用域内。

常见误判点:

  • 全局/静态对象持有的堆内存,在 main 退出后仍被标记为 still reachable —— 这不一定是泄漏,需结合代码判断生命周期
  • 使用 std::shared_ptr 但循环引用,Valgrind 无法识别智能指针语义,只会看到底层 raw pointer 未释放,显示为 definitely lost
  • 第三方库(如 Qt、Boost)内部内存管理可能触发大量 possibly lost,建议先屏蔽其路径:--suppressions=qt.supp

怎么用 Valgrind 检测运行时内存泄漏(含 C++ 示例)

先确保程序可执行文件带调试信息:g++ -g -O0 -std=c++17 main.cpp -o main。然后运行:

valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes ./main

关键参数说明:

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

  • --leak-check=full:启用完整泄漏扫描(默认是 summary)
  • --show-leak-kinds=all:显示 definitely lostindirectly lostpossibly loststill reachable 四类
  • --track-origins=yes:定位未初始化内存读写的源头(对 Conditional jump or move depends on uninitialised value 错误有用)
  • 若程序接受命令行参数,直接跟在 ./main 后面,如:./main --config=test.conf

示例代码片段(故意泄漏):

ChatGPT Website Builder
ChatGPT Website Builder

ChatGPT网站生成器,AI对话快速生成网站

下载
int main() {
    int* p = new int[100];
    // 忘记 delete[] p;
    return 0;
}

Valgrind 输出中会明确标出 at 0x...: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 和对应源文件行号。

Valgrind 在 Linux 下跑不起来?常见启动失败原因

不是所有环境都能直接运行 Valgrind。典型问题包括:

  • 程序用了 ptraceLD_PRELOAD 干预自身加载(如某些反调试手段),Valgrind 会报 Operation not permitted —— 需临时关闭 SELinux 或改用 setsebool -P allow_ptrace 1
  • 目标程序是 setuid/setgid 二进制,Valgrind 默认拒绝加载,加 --trace-children=no 并确认无权限绕过风险
  • 使用 musl libc(如 Alpine Linux)的容器中,Valgrind 不支持 —— 必须换 glibc 基础镜像,或改用 AddressSanitizer
  • 程序启动即崩溃并输出 Invalid read of size X,往往是因为未初始化指针解引用,优先检查 --track-origins=yes 定位源头

比 Valgrind 更快的替代方案:AddressSanitizer(ASan)

Valgrind 运行慢(5–20 倍)、内存开销大,日常开发推荐 ASan:编译期注入检测逻辑,运行仅慢 2 倍左右,且能捕获 use-after-free、buffer overflow 等更多问题。

启用方式:

  • 编译:g++ -g -fsanitize=address -fno-omit-frame-pointer main.cpp -o main
  • 运行:./main,崩溃时自动打印详细错误位置和内存状态
  • 注意:ASan 与 Valgrind 互斥,不能同时启用;且 -O1 及以上才建议开启,-O0 可能漏报
  • ASan 不报告 still reachable 类泄漏,只报实际非法访问或未释放内存(通过 __lsan_enable() + __lsan_do_leak_check() 手动触发)

真正复杂的是多线程场景下的假阳性 —— Valgrind 的 helgrind 模式或 ASan 的 -fsanitize=thread(TSan)才能覆盖,但它们各自有独立的误报模式和性能代价。

热门AI工具

更多
DeepSeek
DeepSeek

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

豆包大模型
豆包大模型

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

通义千问
通义千问

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

腾讯元宝
腾讯元宝

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

文心一言
文心一言

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

讯飞写作
讯飞写作

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

即梦AI
即梦AI

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

ChatGPT
ChatGPT

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

相关专题

更多
视频后缀名都有哪些
视频后缀名都有哪些

视频后缀名都有avi、mpg、mpeg、rm、rmvb、flv、wmv、mov、mkv、ASF、M1V、M2V、MPE、QT、VOB、RA、RMJ、RMS、RAM、等等。更多关于视频后缀名的相关知识,详情请看本专题下面的文章,php中文网欢迎大家前来学习。

3585

2023.10.31

C++ Qt图形开发
C++ Qt图形开发

本专题专注于 C++ Qt框架在图形界面开发中的应用,系统讲解窗口设计、信号与槽机制、界面布局、事件处理、数据库连接与跨平台打包等核心技能,通过多个桌面应用项目实战,帮助学员快速掌握 Qt 框架并独立完成跨平台GUI软件的开发。

71

2025.08.15

C++ 图形界面开发基础(Qt方向)
C++ 图形界面开发基础(Qt方向)

本专题系统讲解 使用 C++ 与 Qt 进行图形界面(GUI)开发的核心技能,内容涵盖 Qt 项目结构、窗口组件、信号与槽机制、事件处理、布局管理、资源管理,以及跨平台编译与打包流程。通过多个小型桌面应用实战案例,帮助学习者掌握从界面设计到功能实现的完整 GUI 开发能力。

82

2025.12.05

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

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

404

2023.07.18

堆和栈区别
堆和栈区别

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

583

2023.08.10

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

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

404

2023.07.18

堆和栈区别
堆和栈区别

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

583

2023.08.10

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

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

613

2023.08.10

Golang处理数据库错误教程合集
Golang处理数据库错误教程合集

本专题整合了Golang数据库错误处理方法、技巧、管理策略相关内容,阅读专题下面的文章了解更多详细内容。

39

2026.02.06

热门下载

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

精品课程

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

共48课时 | 8.7万人学习

Git 教程
Git 教程

共21课时 | 3.4万人学习

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

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