使用 Visual Studio 在 C++ 应用程序中查找内存泄漏
在 Linux 中,我一直使用 valgrind 来检查应用程序中是否存在内存泄漏.Windows 中的等价物是什么?这可以用 Visual Studio 2010 完成吗?
解决方案Visual Studio 2019 有一个不错的内存分析工具,它可以在调试时交互使用或通过编程(无需调试)使用,我在这两种情况下都展示了一个最小的例子在下面.
主要思想是在进程开始和结束时对堆进行快照,然后比较内存状态以检测潜在的内存泄漏.
交互式
创建以下 main.cpp
文件(在新的控制台应用程序中):
#include int main(){int a = 1;字符* s = 新字符[17];strcpy_s(s,17,stackoverflow_pb");字符* ss = 新字符[14];strcpy_s(ss, 14, stackoverflow");删除[] ss;返回0;}
然后:
- 在第一行int a..."上放置一个断点
- 点击调试>窗口 >显示诊断工具;并选择内存使用情况
- 然后调试代码(F5),当断点被命中时,点击内存使用情况摘要工具栏上的
Take snapshot
. - 转到最后一行return 0.."(
跳过
(F10)几次)并拍摄另一个快照. - 点击第二个快照中的红色箭头(在内存使用选项卡中)
- 这将打开一个新的快照";选项卡,允许您将此快照与第一个(或另一个)进行比较并检测内存泄漏.在此示例中,变量
s
(stackoverflow_pb) 存在内存泄漏.您可以通过双击char[]"找到它.对象.
以上过程的关键步骤如下图所示:
通过编程
将代码替换为以下内容:
#include #include windows.h"#define _CRTDBG_MAP_ALLOC//获取更多细节#include #include //用于malloc和freeint main(){_CrtMemState 已售出;_CrtMemState sNew;_CrtMemState sDiff;_CrtMemCheckpoint(&sOld);//拍摄快照字符* s = 新字符[17];strcpy_s(s, 17, stackoverflow_pb");字符* ss = 新字符[14];strcpy_s(ss, 14, stackoverflow");删除[] ss;_CrtMemCheckpoint(&sNew);//拍摄快照if (_CrtMemDifference(&sDiff, &sOld, &sNew))//如果有差异{OutputDebugString(L"-----------_CrtMemDumpStatistics ---------");_CrtMemDumpStatistics(&sDiff);OutputDebugString(L"-----------_CrtMemDumpAllObjectsSince ---------");_CrtMemDumpAllObjectsSince(&sOld);OutputDebugString(L"-----------_CrtDumpMemoryLeaks ---------");_CrtDumpMemoryLeaks();}返回0;}
它做同样的事情,但通过代码,所以你可以将它集成到自动构建系统中,功能
要获取更多信息,请参阅以下链接:
- 交互式分析:测量 Visual Studio 中的内存使用情况
- 通过编程:使用 CRT 库查找内存泄漏 和 CRT 调试堆文件(也用于堆损坏)
In Linux, I have been using valgrind for checking if there are memory leaks in an application. What is the equivalent in Windows? Can this be done with Visual Studio 2010?
解决方案Visual Studio 2019 has a decent memory analysis tool, it may be used interactively while debugging or by programming (without debugging), I show a minimal example in both cases in the following.
The main idea is to take a snapshot of the heap at the beginning and at the end of the process, then to compare the states of memory to detect potential memory leaks.
Interactively
Create the following main.cpp
file (in a new console application) :
#include <string.h>
int main()
{
int a = 1;
char* s = new char[17];
strcpy_s(s,17,"stackoverflow_pb");
char* ss = new char[14];
strcpy_s(ss, 14,"stackoverflow");
delete[] ss;
return 0;
}
Then :
- Put a breakpoint on the first line "int a..."
- Click Debug > Windows > Show Diagnostic Tools; and pick memory usage
- Then debug the code (F5), when the breakpoint is hit, click
Take snapshot
on the Memory Usage summary toolbar. - Go to the last line "return 0.." (
step over
(F10) several times) and take another snapshot. - Click on the red arrow in the second snapshot (in memory usage tab)
- this will open a new "snapshot" tab that permits you to compare this snapshot with the first one (or another one) and to detect memory leaks. In this example there is a memory leak for variable
s
(stackoverflow_pb). You can find it by double click the "char[]" object.
The key steps of the above procedure are shown in the following image:
By programming
Replace the code with the following:
#include <iostream>
#include "windows.h"
#define _CRTDBG_MAP_ALLOC //to get more details
#include <stdlib.h>
#include <crtdbg.h> //for malloc and free
int main()
{
_CrtMemState sOld;
_CrtMemState sNew;
_CrtMemState sDiff;
_CrtMemCheckpoint(&sOld); //take a snapshot
char* s = new char[17];
strcpy_s(s, 17, "stackoverflow_pb");
char* ss = new char[14];
strcpy_s(ss, 14, "stackoverflow");
delete[] ss;
_CrtMemCheckpoint(&sNew); //take a snapshot
if (_CrtMemDifference(&sDiff, &sOld, &sNew)) // if there is a difference
{
OutputDebugString(L"-----------_CrtMemDumpStatistics ---------");
_CrtMemDumpStatistics(&sDiff);
OutputDebugString(L"-----------_CrtMemDumpAllObjectsSince ---------");
_CrtMemDumpAllObjectsSince(&sOld);
OutputDebugString(L"-----------_CrtDumpMemoryLeaks ---------");
_CrtDumpMemoryLeaks();
}
return 0;
}
It does the same thing but by code, so you can integrate it in an automatic build system, the functions _CrtMemCheckpoint
take the snapshots and _CrtMemDifference
compare the memory states of snapshot and returns true is they are different.
Since it is the case, it enters the conditional block and prints details about the leaks via several functions (see _CrtMemDumpStatistics , _CrtMemDumpAllObjectsSince and _CrtDumpMemoryLeaks - the latter doesn't require snapshots).
To see the output, put a break point in the last line "return 0", hit F5
and look at the debug console. Here is the output :
To get more information, see the following links :
- Interactive analysis : Measure memory usage in Visual Studio
- via programming : Find memory leaks with the CRT library and CRT debug Heap Files (for heap corruption also)
相关文章