用VLD调查VC内存泄漏

一、发现内存泄漏

使用VS2022,发现提示有内存泄漏,检查了所有的new,确认都有相应的delete释放。

Detected memory leaks!
Dumping objects ->
{1914} normal block at 0x0000021FDFFBD2E0, 48 bytes long.Data: <`               > 60 E2 FB DF 1F 02 00 00 CD CD CD CD CD CD CD CD 
{1907} normal block at 0x0000021FDFFC22C0, 16 bytes long.Data: <8               > 38 F5 FA DF 1F 02 00 00 00 00 00 00 00 00 00 00 
{1838} normal block at 0x0000021FDFFBCE10, 48 bytes long.Data: <                > 90 DF FB DF 1F 02 00 00 CD CD CD CD CD CD CD CD 
{1831} normal block at 0x0000021FDFFCCE10, 16 bytes long.Data: <8               > 38 FB FA DF 1F 02 00 00 00 00 00 00 00 00 00 00 
{1699} normal block at 0x0000021FDFFBCB00, 48 bytes long.Data: <@               > 40 BB F8 DF 1F 02 00 00 88 BB F8 DF 1F 02 00 00 
{1692} normal block at 0x0000021FDFFCD450, 16 bytes long.Data: <8               > 38 F9 FA DF 1F 02 00 00 00 00 00 00 00 00 00 00 
{1683} normal block at 0x0000021FDFFBD0B0, 48 bytes long.Data: <        X       > 10 AF F8 DF 1F 02 00 00 58 AF F8 DF 1F 02 00 00 
{1676} normal block at 0x0000021FDFFCCDC0, 16 bytes long.Data: <                > B8 F4 FA DF 1F 02 00 00 00 00 00 00 00 00 00 00 
Object dump complete.

手工很难排查,需要使用工具了。

二、安装VLD

从往上搜索下载VLD,Visual Leak Detector | Enhanced Memory Leak Detection for Visual C++

下载最新版,双击安装,默认路径在C:\Program Files (x86)\Visual Leak Detector\下。

三、设置编译环境

在主程序的stdafx.h文件中,afxwin.h头文件之前,加入vld.h头文件。

// 关闭 MFC 对某些常见但经常可放心忽略的警告消息的隐藏
#define _AFX_ALL_WARNINGS#include "vld.h"#include <afxwin.h>         // MFC 核心组件和标准组件
#include <afxext.h>         // MFC 扩展#include <afxdisp.h>        // MFC 自动化类

添加头文件路径:C:\Program Files (x86)\Visual Leak Detector\include;

添加vld.lib类库应用

把C:\Program Files (x86)\Visual Leak Detector\bin\Win64和C:\Program Files (x86)\Visual Leak Detector\lib\Win64目录下的所有文件都复制到当前工程的.\x64\Debug路径下。添加类库的路径:

然后编译即可。

四、检测内存泄漏

运行之后,查看程序加载的模块,确认vld类库加载成功

退出程序,显示VLD已经检测出内存泄漏,单给出的信息不明所以。。

WARNING: Visual Leak Detector detected memory leaks!
---------- Block 22 at 0x00000000962B2B80: 248 bytes ----------Leak Hash: 0x656456F1, Count: 1, Total 248 bytesCall Stack (TID 19720):ucrtbased.dll!malloc_dbg()mfc140d.dll!0x00007FFFC44332DA()mfc140d.dll!0x00007FFFC4579350()mfc140d.dll!0x00007FFFC457938D()mfc140d.dll!0x00007FFFC49A8C95()mfc140d.dll!0x00007FFFC4908D3A()mfc140d.dll!0x00007FFFC4908430()mfc140d.dll!0x00007FFFC4A2C92C()mfc140d.dll!0x00007FFFC4A26474()mfc140d.dll!0x00007FFFC4531F05()mfc140d.dll!0x00007FFFC451D9E0()mfc140d.dll!0x00007FFFC451C1B8()mfc140d.dll!0x00007FFFC444839B()mfc140d.dll!0x00007FFFC47A163E()E:\Work\09.SourceCode\ArtecRoth.cpp (71): ArtecRoth.exe!CArtecRothApp::InitInstance()mfc140d.dll!0x00007FFFC4A2CA3C()D:\a\_work\1\s\src\vctools\VC7Libs\Ship\ATLMFC\Src\MFC\appmodul.cpp (26): ArtecRoth.exe!WinMain()D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl (107): ArtecRoth.exe!invoke_main()D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl (288): ArtecRoth.exe!__scrt_common_main_seh() + 0x5 bytesD:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl (331): ArtecRoth.exe!__scrt_common_main()D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_winmain.cpp (17): ArtecRoth.exe!WinMainCRTStartup()KERNEL32.DLL!BaseThreadInitThunk() + 0x14 bytesntdll.dll!RtlUserThreadStart() + 0x21 bytesData:00 00 00 00    00 00 00 00    08 80 30 96    28 01 00 00     ........ ..0.(...28 1A 10 6F    00 00 00 00    58 75 D0 C4    FF 7F 00 00     (..o.... Xu......28 0A 2E 96    28 01 00 00    FD 19 10 11    00 00 00 00     (...(... ........C8 75 D0 C4    FF 7F 00 00    88 2B 2B 96    28 01 00 00     .u...... .++.(...B3 14 10 C4    FF FF FF FF    98 75 D0 C4    FF 7F 00 00     ........ .u......10 0A 2E 96    28 01 00 00    20 1A 10 3E    00 00 00 00     ....(... ...>....A8 75 D0 C4    FF 7F 00 00    00 00 00 00    00 00 00 00     .u...... ........91 18 10 01    00 00 00 00    68 75 D0 C4    FF 7F 00 00     ........ hu......40 0A 2E 96    28 01 00 00    4B 1A 10 65    00 00 00 00     @...(... K..e....88 75 D0 C4    FF 7F 00 00    E8 2B 2B 96    28 01 00 00     .u...... .++.(...22 1A 10 3C    00 00 00 00    B8 75 D0 C4    FF 7F 00 00     "..<.... .u......E0 09 2E 96    28 01 00 00    50 1A 30 1B    00 00 00 00     ....(... P.0.....D8 75 D0 C4    FF 7F 00 00    70 0A 2E 96    28 01 00 00     .u...... p...(...12 17 30 FD    FF FF FF FF    E8 75 D0 C4    FF 7F 00 00     ..0..... .u......48 2C 2B 96    28 01 00 00    47 1A 30 53    00 00 00 00     H,+.(... G.0S....F8 75 D0 C4    FF 7F 00 00                                   .u...... ........

说明内存泄露没有发生在主程序中,把上面的编译设置从主程序中去除,在下面调用的dll工程中按同样的方法设置,多个dll工程的话,需要挨个试。

 在dll工程中设置,重新编译后,运行结果果然找到了具体位置。

---------- Block 3747 at 0x00000000C2B10AD0: 48 bytes ----------Leak Hash: 0x60ABD716, Count: 1, Total 48 bytesCall Stack (TID 20788):mfc140d.dll!0x00007FFFC4093200()C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.34.31933\include\xmemory (78): AtcTransRoth.dll!std::_Default_allocate_traits::_Allocate()C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.34.31933\include\xmemory (235): AtcTransRoth.dll!std::_Allocate<16,std::_Default_allocate_traits,0>() + 0xC bytesC:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.34.31933\include\xmemory (836): AtcTransRoth.dll!std::allocator<TransCoil *>::allocate()C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.34.31933\include\vector (1673): AtcTransRoth.dll!std::vector<TransCoil *,std::allocator<TransCoil *> >::_Reallocate_exactly() + 0x10 bytesC:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.34.31933\include\vector (1750): AtcTransRoth.dll!std::vector<TransCoil *,std::allocator<TransCoil *> >::reserve()E:\Work\AtcArray.h (114): AtcTransRoth.dll!vector<TransCoil *>::Reserve() + 0x13 bytesE:\Work\AtcRothData.cpp (182): AtcTransRoth.dll!CAtcRothData::GetCoils()E:\Work\AtcRothData.cpp (831): AtcTransRoth.dll!CAtcRothData::CreateElement() + 0x1B bytesE:\Work\AtcRothData.cpp (616): AtcTransRoth.dll!CAtcRothData::LoadSchemaFromXml() + 0x13 bytesE:\Work\AtcRothData.cpp (34): AtcTransRoth.dll!CAtcRothData::LoadData() + 0x21 bytesE:\Work\ArtecRothDlg.cpp (207): ArtecRoth.exe!CArtecRothDlg::OnEnChangeMfceditbrowse1() + 0x41 bytesmfc140d.dll!0x00007FFFC44A21CC()mfc140d.dll!0x00007FFFC44A1A06()mfc140d.dll!0x00007FFFC4508F2C()

从提示的信息上看是vector申请的内存没有释放。通过仔细查看, 确认是TransWindingElementCoil 结构体中出现了内存泄漏,问题出在了结构体的继承上。

struct TransWindingElement
{CString chName;CString chLabel;AemTransElement emType;AemTransJoint emJoint;
};struct TransWindingElementCoil : TransWindingElement
{vector<TransCoil*> arCoil;
};

在delete释放TransWindingElementCoil  对象是,由于保存的是父结构体的指针,只调用了TransWindingElement的析构函数,而没有调用TransWindingElementCoil 对象的析构函数,造成了vector对象所在内存空间的泄漏。

五、处理方法

给父结构体加虚析构函数

struct TransWindingElement
{virtual ~TransWindingElement() {}CString chName;CString chLabel;AemTransElement emType;AemTransJoint emJoint;
};struct TransWindingElementCoil : TransWindingElement
{vector<TransCoil*> arCoil;
};

运行再无内存泄漏。

六、结束

在编程是需要时刻观察内存泄漏信息,出现内存泄漏要及时处理。堆积时间越长,则越难处理,尤其在运行计算的大循环中,调式内存泄漏极其麻烦。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/126131.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

浅谈wor2vec,RNN,LSTM,Transfermer之间的关系

浅谈wor2vec&#xff0c;RNN&#xff0c;LSTM&#xff0c;Transfermer之间的关系 今天博主谈一谈wor2vec&#xff0c;RNN&#xff0c;LSTM&#xff0c;Transfermer这些方法之间的关系。 首先&#xff0c;我先做一个定位&#xff0c;其实Transfermer是RNN&#xff0c;LSTM&…

基于安卓android微信小程序的旅游app系统

项目介绍 随着人民生活水平的提高,旅游业已经越来越大众化,而旅游业的核心是信息,不论是对旅游管理部门、对旅游企业,或是对旅游者而言,有效的获取旅游信息,都显得特别重要.自助定制游将使旅游相关信息管理工作规范化、信息化、程序化,提供旅游景点、旅游线路,旅游新闻等服务本…

java的内存模型(概念)

在java中&#xff0c;设计之初就有了&#xff1a;主内存、线程工作内存&#xff0c;所以其实每一个线程执行时&#xff0c;都是将主线程copy一份到工作线程&#xff0c;执行修改后&#xff0c;再同步回去。 所以&#xff0c;就有四组内存操作方式&#xff1a; 1、读主内存&…

基于comsol的压力声学-热黏性声学模块模拟一种具有多阶吸声的低频宽带薄超表面

研究背景&#xff1a; 由于传统材料的能量耗散较弱&#xff0c;低频吸声一直是研究人员面临的一个具有挑战性的课题。近年来&#xff0c;声学超材料发展迅速&#xff0c;具有前所未有的优异低频性能。已经设计了一系列亚波长厚度的超材料&#xff0c;以实现对低频声音的100%吸…

C++深入学习part_1

Linux下编译C程序 安装g命令&#xff1a;sudo apt install g 编译命令&#xff1a;$ g *.cc 或者 *.cpp -o fileName; hellworld 编译程序可以看到&#xff1a; namespace命名空间 首先&#xff0c;命名空间的提出是为了防止变量重名冲突而设置的。 浅浅试一下&#xff1…

【RabbitMQ 实战】08 集群原理剖析

上一节&#xff0c;我们用docker-compose搭建了一个RabbitMQ集群&#xff0c;这一节我们来分析一下集群的原理 一、基础概念 1.1 元数据 前面我们有介绍到 RabbitMQ 内部有各种基础构件&#xff0c;包括队列、交换器、绑定、虚拟主机等&#xff0c;他们组成了 AMQP 协议消息…

云安全之等级保护解决方案及应用场景

等保2.0解决方案背景 适应云计算、移动互联网、大数据、物联网和工业控制等新技术发展&#xff0c;在新的技术场景能够顺利开展等级保护工作;《网络安全法》2016年已正式发布&#xff0c;等级保护2.0为了更好配合《网络安全法》的实施&#xff1b;等级保护1.0&#xff0c;在适…

51单片机音乐闹钟秒表倒计时整点报时多功能电子钟万年历数码管显示( proteus仿真+程序+原理图+报告+讲解视频)

51单片机音乐闹钟秒表倒计时整点报时多功能电子钟万年历数码管显示( proteus仿真程序原理图报告讲解视频&#xff09; 讲解视频1.主要功能&#xff1a;2.仿真3. 程序代码4.原理图5. 设计报告6. 设计资料内容清单 51单片机音乐闹钟秒表倒计时整点报时多功能电子钟万年历数码管显…

次方计数的拆贡献法(考虑组合意义)+限定类问题善用值域与位置进行ds:1006T3

对于多次方的计数问题可以考虑拆贡献。 题目问 ∣ S ∣ 3 |S|^3 ∣S∣3&#xff0c; ∣ S ∣ |S| ∣S∣ 表示选的点数。相当于在 ∣ S ∣ |S| ∣S∣ 中选了3次&#xff0c;也就是选了3个可相同的点。 先考虑3个不相同点的贡献&#xff0c;对应任意3个点&#xff0c;必然会对…

【GO 编程语言】面向对象

指针与结构体 文章目录 指针与结构体一、OOP 思想二、继承三、方法四、接口实现五、多态六、空接口七、接口继承八、接口断言九、Type别名 一、OOP 思想 Go语言不是面向对象的语言&#xff0c;这里只是通过一些方法来模拟面向对象&#xff0c;从而更好的来理解面向对象思想 面…

什么,这年头还有人不知道404

写在前面 哥&#xff0c;来帮我看看&#xff0c;这个请求怎么404了&#xff0c;明明接口路径是对的啊&#xff01;一个下午&#xff0c;组里的小哥突然让我帮忙看这个问题&#xff0c;我不禁一惊&#xff0c;啥&#xff0c;这年头了还有人搞不定404&#xff0c;如有还有&#…

国庆中秋宅家自省: Python在Excel中绘图尝鲜

Python3中类的高级语法及实战 Python3(基础|高级)语法实战(|多线程|多进程|线程池|进程池技术)|多线程安全问题解决方案 Python3数据科学包系列(一):数据分析实战 Python3数据科学包系列(二):数据分析实战 Python3数据科学包系列(三):数据分析实战 【一】国庆中秋: 悟 【国…