使用 Visual Studio 在 C++ 应用程序中查找内存泄漏

Finding memory leaks in a C++ application with Visual Studio(使用 Visual Studio 在 C++ 应用程序中查找内存泄漏)
本文介绍了使用 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;}

然后:

  1. 在第一行int a..."上放置一个断点
  2. 点击调试>窗口 >显示诊断工具;并选择内存使用情况
  3. 然后调试代码(F5),当断点被命中时,点击内存使用情况摘要工具栏上的Take snapshot.
  4. 转到最后一行return 0.."(跳过(F10)几次)并拍摄另一个快照.
  5. 点击第二个快照中的红色箭头(在内存使用选项卡中)
  6. 这将打开一个新的快照";选项卡,允许您将此快照与第一个(或另一个)进行比较并检测内存泄漏.在此示例中,变量 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 :

  1. Put a breakpoint on the first line "int a..."
  2. Click Debug > Windows > Show Diagnostic Tools; and pick memory usage
  3. Then debug the code (F5), when the breakpoint is hit, click Take snapshot on the Memory Usage summary toolbar.
  4. Go to the last line "return 0.." (step over (F10) several times) and take another snapshot.
  5. Click on the red arrow in the second snapshot (in memory usage tab)
  6. 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)

这篇关于使用 Visual Studio 在 C++ 应用程序中查找内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

相关文档推荐

How do compilers treat variable length arrays(编译器如何处理变长数组)
Deduce template argument from std::function call signature(从 std::function 调用签名推导出模板参数)
check if member exists using enable_if(使用 enable_if 检查成员是否存在)
Standard Library Containers with additional optional template parameters?(具有附加可选模板参数的标准库容器?)
Uses of a C++ Arithmetic Promotion Header(C++ 算术提升标头的使用)
Parameter pack must be at the end of the parameter list... When and why?(参数包必须位于参数列表的末尾...何时以及为什么?)