0

0

C++ 什么是内存泄漏 C++ Valgrind检测内存泄漏教程【工具】

穿越時空

穿越時空

发布时间:2026-02-01 16:44:02

|

893人浏览过

|

来源于php中文网

原创

内存泄漏指C++中new/malloc后未delete/free,致堆内存持续增长、长期运行引发OOM;Valgrind需-g编译后运行检测,重点关注“definitely lost”类泄漏。

c++ 什么是内存泄漏 c++ valgrind检测内存泄漏教程【工具】

内存泄漏在 C++ 中到底意味着什么

内存泄漏不是程序崩溃,而是程序反复 newmalloc 但没配对调用 deletefree,导致堆内存持续增长、无法回收。它不会立刻报错,但长期运行会耗尽系统内存,引发卡顿、OOM 或被系统 kill。

典型场景包括:类中手动管理指针成员、异常路径遗漏 delete、容器存储裸指针后未清理、回调注册后忘记注销等。

注意:std::unique_ptrstd::shared_ptr 能大幅降低风险,但不等于免疫——比如循环引用、shared_ptr 持有裸指针再 new 出新对象却未交由智能指针接管,照样泄漏。

Valgrind 怎么跑出有效内存泄漏报告

Valgrind 不是编译器插件,而是一个运行时检测工具,必须用它启动你的可执行文件,且程序需用 -g 编译(保留调试符号),否则报告里只有地址,看不到源码行号。

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

基础命令:

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

关键参数说明:

  • --leak-check=full:启用完整泄漏分析(默认是 summary)
  • --show-leak-kinds=all:显示 definitely lost / indirectly lost / possibly lost / still reachable 四类
  • --track-origins=yes:定位未初始化内存的来源(对“use of uninitialised value”类问题极有用)

常见误操作:直接对二进制加 valgrind 却忘了重新编译带 -g;或在 CI 环境中未安装 valgrind 导致命令静默失败;还有人把 valgrind 当成静态分析工具,试图扫描源码——它只作用于运行过程。

讯飞星火
讯飞星火

科大讯飞推出的多功能AI智能助手

下载

看懂 Valgrind 报告里的 “definitely lost” 是关键

Valgrind 将泄漏分四类,真正要优先处理的是 definitely lost:指指针已丢失(/堆上都找不到指向该内存的有效地址),这块内存彻底不可达,100% 泄漏。

示例片段:

==12345== 40 bytes in 1 blocks are definitely lost in loss record 1 of 2
==12345==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==12345==    by 0x4005D9: main (test.cpp:8)

这表示 test.cpp 第 8 行调用了 malloc,但后续没 free,且无任何变量持有该地址。

其他三类含义:

  • indirectly lost:因父块泄漏导致的子指针泄漏(如结构体中指针成员指向的内存)
  • possibly lost:指针可能还在栈上,但 Valgrind 不确定是否还能访问(比如存在指针运算或 cast)
  • still reachable:程序退出前仍有指针指向它(如全局缓存、单例内部指针),不一定算 bug,但得人工确认是否合理

C++ 项目中 Valgrind 的实际使用限制

Valgrind 在 Linux 上工作良好,但 macOS 和 Windows 原生不支持;macOS 用户只能靠 AddressSanitizer(Clang/GCC 都支持)替代。

它不能检测所有内存问题:

  • 不捕获栈溢出或越界读(要用 AddressSanitizer
  • 对多线程竞争检测弱(Helgrind 模块可用但开销大、误报多)
  • 无法识别逻辑泄漏(比如缓存不断 insert 却从不 erase,内存一直涨但每个指针都“活着”)
  • 若程序用 mmap 或自定义分配器绕过 malloc,默认模式下 Valgrind 会漏检

真实项目建议:CI 中固定跑 Valgrind + ASan 组合;本地开发时,对核心模块写带 teardown 的单元测试,再用 Valgrind 包裹单测执行;别等上线后 OOM 才想起查泄漏——那时堆栈早已被冲掉。

热门AI工具

更多
DeepSeek
DeepSeek

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

豆包大模型
豆包大模型

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

通义千问
通义千问

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

腾讯元宝
腾讯元宝

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

文心一言
文心一言

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

讯飞写作
讯飞写作

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

即梦AI
即梦AI

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

ChatGPT
ChatGPT

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

相关专题

更多
golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

262

2025.06.09

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

192

2025.07.04

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

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

399

2023.07.18

堆和栈区别
堆和栈区别

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

575

2023.08.10

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

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

399

2023.07.18

堆和栈区别
堆和栈区别

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

575

2023.08.10

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

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

546

2023.08.10

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

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

210

2025.12.24

go语言 注释编码
go语言 注释编码

本专题整合了go语言注释、注释规范等等内容,阅读专题下面的文章了解更多详细内容。

30

2026.01.31

热门下载

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

精品课程

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

共48课时 | 8.2万人学习

Git 教程
Git 教程

共21课时 | 3.2万人学习

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

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