Windows系统下使用VS排查内存泄露的两种办法
目录
- 使用Windows编程排查
- 排查内存泄漏的原理
- 一个内存泄漏demo
- 排查内存泄漏
- 把内存泄漏的位置注释掉看下效果
- 使用VS诊断工具查看
- 一段内存泄漏demo
内存泄露应该是程序员或者是C/C++ 程序员最不想遇到的问题,也是最难解决的问题.
今天看视频,有位前辈在分享在Windows系统下使用VS排查内存泄漏的方法,于是记下前辈的经验,以便日后自己遇到可以参考。
使用Windows编程排查
排查内存泄漏的原理
这种方式是使用把new重定义为微软运行时库提供的重载版本,这个重载版本的new专门用于内存调试,它能把没有释放的内存通通打印出来。
一个内存泄漏demo
#define __CRT_SECURE_NO_WARNINGS
#include <iostream>int main()
{char* buffer = new char[100];std::cout << "helloworld" << std::endl; return 0;
}
一个简单的内存泄露demo
第一行宏定义不用管这个是由于我使用的是VS2022版本的编译器,如果使用C/C++函数,有些函数已经不推荐使用了,这里就会报错,为了不报错加的这行宏定义。
__CRT_SECURE_NO_WARNINGS介绍
排查内存泄漏
#define __CRT_SECURE_NO_WARNINGS#include <Windows.h>
#include <iostream>
#include <crtdbg.h>#ifdef _DEBUG
#define DEBUG_NEW new(_NORMAL_BLOCK,__FILE__,__LINE__)
#define new DEBUG_NEW
#endif // _DEBUGint main()
{_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);char* buffer = new char[100];std::cout << "helloworld" << std::endl;_CrtDumpMemoryLeaks();return 0;
}
其实在debug下添加头文件
#include <Windows.h>
#include <crtdbg.h>
在代码开始的时候添加
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
在代码结束的时候添加
_CrtDumpMemoryLeaks();
然后运行代码,在运行完之后会显示那里内存泄漏了。
1显示那个文件哪一行泄漏了,2是显示泄漏了多少字节,3是泄漏的标志。
把内存泄漏的位置注释掉看下效果
#define __CRT_SECURE_NO_WARNINGS#include <Windows.h>
#include <iostream>
#include <crtdbg.h>#ifdef _DEBUG
#define DEBUG_NEW new(_NORMAL_BLOCK,__FILE__,__LINE__)
#define new DEBUG_NEW
#endif // _DEBUGint main()
{_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);//char* buffer = new char[100];std::cout << "helloworld" << std::endl;_CrtDumpMemoryLeaks();return 0;
}
这是没有内存泄漏的效果。
使用VS诊断工具查看
如果使用了VirtualAlloc函数,或者实现了自己的内存管理。这种情况是无法通过上面的方式找到内存泄漏的。那可以采用VS debug时的诊断工具。
VirtualAlloc函数
一段内存泄漏demo
#define __CRT_SECURE_NO_WARNINGS
#pragma warning(disable:4996)
#include <iostream>int main()
{for (int i = 0; i < 1000000; ++i){char* buffer = new char[100];_sleep(1000);} std::cout << "helloworld" << std::endl;getchar();return 0;
}
按下1和2 的时候接着按下3,这里3一共分两次按下,第一次按下会出现一次快照,等一会再按一下,每次按下都会截取当前的内存快照。
点击4和5就能看到两次快照之间的内存申请没有释放的内存,当然并不是所有的都有泄漏,需要根据具体代码排查。
我这里比较简单,就这个一个。具体工程应该是非常多的。需要耐心排查。