剑痴乎

  • 首页
  • 文章分类
    • 音视频
    • WebRTC
    • 编程之美
    • Linux
    • Windows
    • 生活点滴
    • 校园生活
  • 参考
    • API参考
    • 实用工具
    • 测试音视频
    • 文档
  • 留言板
  • 关于
剑痴乎
代码为剑,如痴如醉
  1. 首页
  2. Windows
  3. 正文

Visual Studio检查内存泄露方法

2016年6月7日 5097点热度 35人点赞 1条评论

在测试自己写的程序时,我们一般都会去任务管理器查看程序内存状况,看内存是否随着时间一直增长,如果一直增长,那恭喜了,程序内存泄露了。

编写程序时要养成良好习惯,申请的内存要记得释放,遇到内存泄露时要认真查看申请的内存释放了没,除此之外,我们也可以通过第三方帮助我们发现程序内存泄露状况。

_CrtDumpMemoryLeaks函数

系统自带的 C Run-Time (CRT)库可以帮助我们检测内存泄露,使用很简单。
1)包含相应头文件

C++
1
2
3
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>

2)在程序退出地方,加上:

C++
1
_CrtDumpMemoryLeaks();

在调用_CrtDumpMemoryLeaks函数前我们要确保释放了该释放的内存,最后程序结束后在Output窗口就会打印出内存泄露信息。

3)如果我们程序有多个退出点,需要都添加上_CrtDumpMemoryLeaks函数,比较麻烦,此刻_CrtSetDbgFlag 函数就比较方便了。在程序初始化地方加上:

C++
1
_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );

这个函数会在我们程序每个退出点自动执行_CrtDumpMemoryLeaks 函数。

对于如何定位内存泄露代码以及其他使用,可以看下MSDN上的介绍:https://msdn.microsoft.com/en-us/library/x98tx3cf.aspx。

Visual Leak Detector(VLD)插件

给我们的VS装上该插件,下载地址:https://vld.codeplex.com/,使用方法很简单,安装完插件后,在我们要检测的文件加上

C++
1
#include <vld.h>

然后在debug模式下运行,在Output窗口即可查看详细泄露信息,其实该插件原理就是上一节说到的CRT库。比如我们下面一段测试代码:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include<iostream>
#include <vld.h>
 
void LeakTest()
{
char *memory = new char[10];
int a = 10;
memcpy(memory, &a, sizeof(a));
/*if (nullptr != memory)
{
delete[] memory;
memory = nullptr;
}*/
}
 
 
int main()
{
LeakTest();
 
return 0;
}

上述代码我们注释掉了delete部分,debug运行结束后我们可以看到Output窗口显示泄露了10字节,同时打印出泄露的堆栈,如果程序复杂的话,我们可以在Output窗口双击泄露的堆栈定位到相应代码。

VS2015内存快照

在VS2015引入了强大的内存查看工具,在程序运行时,右侧窗口我们可以查看程序内存状况。通过截取某两个不同时刻的内存快照,进行对比,可以快速找到泄露部分。同样还是上面的测试代码,不过得注释掉include vld头文件这一行,我们按如下步骤定位泄露部分。
1)在LeakTest处打个断点,debug运行,在右侧窗口->Memory Usage标签页中启用Heap Profiling。

2)点击Take Snapshot,相当于一次拍照(这图标就是一个相机),此刻下面即可显示当前分配的内存大小,堆大小。

3)执行完测试函数后,我们再次点击Take Snapshot按钮,此刻提示了与上一次快照的变化。

4)点击括号处(+1)或(+0.04KB)变化部分链接。

5)在左侧窗口查看与前一次快照对比,具体什么数据造成内存变化。

6)双击后查看定义为char类型数据的具体实例,我们程序中只定义了一个char类型数据,所以只有一个实例,再双击某个实例可以定位到具体代码,同时查看相应堆栈调用,由于测试程序太简单了,所以这里看不到。

拿我以前写的一个复杂程序举例,程序中我定义了多个CString类型数据,点击查看CString数据具体实例。

我们可以看到多个CString数据实例,点击某个实例就可以看到堆栈调用了,双击具体的堆栈调用可以定位到具体代码。

详细使用可以参考微软官方博客:https://blogs.msdn.microsoft.com/vcblog/2015/10/21/memory-profiling-in-visual-c-2015/,我就不细说了。

本作品采用 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议 进行许可
标签: VC++
最后更新:2018年12月23日

Jeff

管理员——代码为剑,如痴如醉

打赏 点赞
< 上一篇
下一篇 >

文章评论

  • SethSnowe

    技术牛人,您好,Wondershare公司正在招聘C++研发牛人,为中国软件筑梦,如果您感兴趣一起加入其中,可以试用邮箱联系。期待您的回复。https://www.wondershare.cn/

    2020年8月24日
    回复
  • razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
    回复 SethSnowe 取消回复

    这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理。

    版权声明

    为支持原创,创作更好的文章,未经许可,禁止任何形式的转载与抄袭,如需转载请邮件私信!本人保留所有法定权利。违者必究!

    文章目录
    • _CrtDumpMemoryLeaks函数
    • Visual Leak Detector(VLD)插件
    • VS2015内存快照
    最近评论
    ztt 发布于 1 个月前(04月05日) 你好,想看里面的视频和图片为什么没有显示呢?需要下flash吗还是什么。
    huowa222 发布于 1 个月前(03月26日) 同问
    邱国禄 发布于 3 个月前(02月17日) Receive Delta以0.25ms为单位,reference time以64ms为单位,kDe...
    啊非 发布于 4 个月前(12月30日) 大神,请教一个问题: constexpr int kBaseScaleFactor = Tran...
    啊非 发布于 4 个月前(12月30日) reference time:3字节,表示参考时间,以64ms为单位,但是 代码里面是 Trans...
    相关文章
    • 如何让MFC或其他VS编译的程序支持高DPI
    • VC实现程序单实例运行
    • 使用libVLC实现的播放器:支持双击全屏
    • FireBreath插件IE浏览器中文字符乱码问题
    • 基于FireBreath的npapi插件在Firefox下的调试

    COPYRIGHT © 2024 jianchihu.net. ALL RIGHTS RESERVED.

    Theme Kratos Made By Seaton Jiang