0

0

C++如何检测内存泄漏源头_C++使用Visual Studio检测内存泄漏【调试】

尼克

尼克

发布时间:2026-02-05 14:05:08

|

142人浏览过

|

来源于php中文网

原创

必须调用_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF)并包含,且仅在_DEBUG下生效;{123}是分配序号而非源码行号,需配合_CrtSetBreakAlloc(123)定位。

c++如何检测内存泄漏源头_c++使用visual studio检测内存泄漏【调试】

Visual Studio 调试器中开启内存泄漏检测必须加 _CrtSetDbgFlag

默认情况下,VS 的 C 运行时(CRT)不会自动报告内存泄漏,哪怕你用了 new 没配 delete。关键动作是手动启用调试堆并设置报告级别——最常用的是在 main() 开头或 WinMain() 里调用:

_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);

注意两点:
• 必须包含 头文件,且仅在 _DEBUG 宏定义下生效;
_CRTDBG_LEAK_CHECK_DF 表示程序退出时自动检查泄漏,不是实时监控;
• 如果只设了 _CRTDBG_ALLOC_MEM_DF 而没加泄漏检查标志,运行结束时不会输出任何泄漏信息。

泄漏报告里的 {123} 行号不是源码行号,而是分配序号

VS 输出的泄漏信息形如:

Detecting memory leaks...
Detected memory leaks!
Dumping objects ->
{18} normal block at 0x00B9A568, 4 bytes long.
Data: < > CD CD CD CD

这个 {18} 是 CRT 内部按分配顺序给的编号,不是你代码第 18 行。要定位源头,得配合 _CrtSetBreakAlloc(18) 在第 18 次分配时中断:

_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
_CrtSetBreakAlloc(18); // 加在 main 开头,运行后会在该次 new/malloc 处中断

常见误区:
• 直接看泄漏报告里“file:line”字段——它只对用 _malloc_dbg 或重载了带文件/行号参数的 operator new 才有效;
• 忘记在 Debug 模式下编译:Release 模式下 _Crt*() 函数全为空操作;
• 在 DLL 中初始化时调用太早(比如 DLL_PROCESS_ATTACH 里),此时 CRT 堆可能还没准备好。

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

达芬奇
达芬奇

达芬奇——你的AI创作大师

下载

C++ 类中重载 operator new 才能获得精准文件名和行号

标准 new 不传位置信息,所以 CRT 默认无法记录调用点。想让泄漏报告直接显示 myfile.cpp(42),需全局或按类重载带调试参数的版本:

#ifdef _DEBUG
void* operator new(size_t size, const char* file, int line) {
return _malloc_dbg(size, _NORMAL_BLOCK, file, line);
}
#define new new(__FILE__, __LINE__)
#endif

实际使用时要注意:
• 宏定义 #define new 必须放在所有头文件之后、你的源文件代码之前(常放在 stdafx.h 尾或单独的 debug_new.h 中);
• 第三方库如果也重载了 operator new,可能冲突,此时建议只在自己的模块中局部启用;
std::vectorstd::string 等 STL 容器内部分配通常不走你的重载(除非自定义 allocator),它们的泄漏仍显示为 {N} 序号。

VS 的「诊断工具」窗口只能看到堆大小趋势,不能定位具体泄漏点

按 Ctrl+Alt+F2 打开诊断工具后,内存使用曲线和快照对比对性能分析有用,但快照里列出的对象类型(如 “std::string”、“char[]”)不带分配,也无法关联到源码行。它和 CRT 泄漏检测是两套机制:
• CRT 报告依赖调试堆标记,输出文本到输出窗口;
• 诊断工具基于 ETW 事件采集,更轻量但信息粒度粗;
• 若项目启用了 /MT(静态链接 CRT),而诊断工具期望动态 CRT,则可能完全不显示托管/本地内存混合视图。

真正能定位到哪一行 new 没配 delete 的,还是靠 _CrtSetBreakAlloc 配合断点,或者用第三方工具如 Visual Leak Detector(VLD),它会自动 hook 所有分配路径并打印完整调用栈。

热门AI工具

更多
DeepSeek
DeepSeek

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

豆包大模型
豆包大模型

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

通义千问
通义千问

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

腾讯元宝
腾讯元宝

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

文心一言
文心一言

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

讯飞写作
讯飞写作

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

即梦AI
即梦AI

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

ChatGPT
ChatGPT

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

相关专题

更多
string转int
string转int

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

585

2023.08.02

typedef和define区别
typedef和define区别

typedef和define区别在类型检查、作用范围、可读性、错误处理和内存占用等。本专题为大家提供typedef和define相关的文章、下载、课程内容,供大家免费下载体验。

112

2023.09.26

define的用法
define的用法

define用法:1、定义常量;2、定义函数宏:3、定义条件编译;4、定义多行宏。更多关于define的用法的内容,大家可以阅读本专题下的文章。

343

2023.10.11

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

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

400

2023.07.18

堆和栈区别
堆和栈区别

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

579

2023.08.10

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

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

400

2023.07.18

堆和栈区别
堆和栈区别

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

579

2023.08.10

数据库Delete用法
数据库Delete用法

数据库Delete用法:1、删除单条记录;2、删除多条记录;3、删除所有记录;4、删除特定条件的记录。更多关于数据库Delete的内容,大家可以访问下面的文章。

279

2023.11.13

java连接字符串方法汇总
java连接字符串方法汇总

本专题整合了java连接字符串教程合集,阅读专题下面的文章了解更多详细操作。

7

2026.02.05

热门下载

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

精品课程

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

共58课时 | 4.7万人学习

Pandas 教程
Pandas 教程

共15课时 | 1万人学习

ASP 教程
ASP 教程

共34课时 | 4.5万人学习

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

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