讲师中心 微信公众号
AI工具推荐 视频效率加速

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

千敏吖_6186

千敏吖_6186

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

|

452人浏览过

|

来源于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 lost、indirectly lost、possibly lost、still reachable 四类
  • --track-origins=yes:定位未初始化内存读写的源头(对 Conditional jump or move depends on uninitialised value 错误有用)
  • 若程序接受命令行参数,直接跟在 ./main 后面,如:./main --config=test.conf

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

Obsidian (Linux)
Obsidian (Linux)

操作 Obsidian 库(纯 Markdown 笔记),并通过 notesmd-cli 实现自动化。

下载
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。典型问题包括:

  • 程序用了 ptrace 或 LD_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工具

更多
Loomy
Loomy Hot

一款AI工具,主要用于科大讯飞发布的桌面级 AI 助理,比 OpenClaw 更易用、更安全!,适合需要提升相关任务效率的用户。

音述AI
音述AI Hot

一款AI音频处理工具,主要用于音述AI是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

超级麦吉

一款通过数字员工协作完成调研、数据分析与文档制作的AI办公平台。

Atoms
Atoms Hot

Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

Lovart
Lovart Hot

一款面向视觉设计创作的AI设计平台,可通过智能体和画布工作流辅助制作海报、Logo、网页、PPT及其他视觉内容。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

相关专题

更多
C++ Qt图形开发
C++ Qt图形开发

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

5362

2025.08.15

C++桌面程序开发
C++桌面程序开发

本专题聚焦 C++ 在桌面端图形界面应用开发中的实战应用,系统讲解 Qt 框架的信号与槽机制、界面布局管理、事件响应、数据交互、样式美化与多窗口应用设计等核心知识。通过实战案例(如记事本应用、数据管理工具、系统监控面板),帮助学习者掌握 从UI设计到完整桌面软件开发的C++工程化能力。

1434

2025.10.23

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

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

1441

2025.12.05

C++ 智能指针与现代内存管理
C++ 智能指针与现代内存管理

深入讲解 C++ 现代内存管理的核心工具——智能指针,涵盖 unique_ptr 独占所有权语义、shared_ptr 引用计数机制与循环引用问题、weak_ptr 弱引用的应用场景、make_unique/make_shared 工厂函数的性能优势、自定义删除器的编写、RAII 资源管理思想的实践,以及从裸指针迁移到智能指针的重构策略,帮助开发者编写安全无泄漏的现代 C++ 代码。

379

2026.04.23

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

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

6267

2023.07.18

堆和栈区别
堆和栈区别

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

2628

2023.08.10

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

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

6267

2023.07.18

堆和栈区别
堆和栈区别

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

2628

2023.08.10

Vite 项目如何打包和部署
Vite 项目如何打包和部署

Vite项目打包部署专题汇集生产构建、产物预览、输出目录、资源路径、Nginx与GitHub Pages部署及常见白屏和路由404问题的已审核文章,帮助读者完成上线流程。

40

2026.10.28

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Python uv官方安装与入门文档
Python uv官方安装与入门文档

共0课时 | 0人学习

Buffalo框架快速入门指南
Buffalo框架快速入门指南

共0课时 | 0人学习

Valgrind支持平台说明
Valgrind支持平台说明

共0课时 | 0人学习

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn