【发布时间】:2011-06-15 00:04:44
【问题描述】:
在 Linux 中,我一直使用 valgrind 来检查应用程序中是否存在内存泄漏。 Windows 中的等价物是什么?这可以用 Visual Studio 2010 完成吗?
【问题讨论】:
标签: c++ visual-studio visual-studio-2010 memory-leaks valgrind
在 Linux 中,我一直使用 valgrind 来检查应用程序中是否存在内存泄漏。 Windows 中的等价物是什么?这可以用 Visual Studio 2010 完成吗?
【问题讨论】:
标签: c++ visual-studio visual-studio-2010 memory-leaks valgrind
您可以使用 DevPartner 工具在 Visual Studio 中查找 C++ 应用程序中的内存泄漏。
【讨论】:
Visual Leak Detector 怎么样?它不是内置的,但我认为它是最受欢迎的。
【讨论】:
C++ Memory Validator 在使用 Visual Studio、Delphi 和其他编译器构建的本机 Windows 程序中查找内存并处理泄漏。速度快,可以处理大型工作负载(一些用户一次跟踪数十亿次分配和解除分配)。
披露:我是 C++ Memory Validator 的设计者。我们构建它是因为当我们与 SolidWorks R&D Ltd 合作时,其他工具无法处理工作量。
【讨论】:
Visual Studio 2015 及更高版本具有本机内存泄漏诊断工具,详情请查看:https://dzone.com/articles/native-memory-leak-diagnostics。
【讨论】:
Dr. Memory 是一个内存监控工具,能够识别内存相关的编程错误,例如访问未初始化的内存、访问不可寻址的内存(包括分配的堆单元之外和堆下溢和溢出)、访问已释放的内存、双释放、内存泄漏和(在 Windows 上)处理泄漏、GDI API 使用错误以及对未保留线程本地存储槽的访问。
博士。内存可在未修改的应用程序二进制文件上运行,该二进制文件在商用 IA-32、AMD64 和 ARM 硬件上运行在 Windows、Linux、Mac 或 Android 上。
博士。内存建立在DynamoRIO动态检测工具平台之上。
【讨论】:
Application Verifier 是检测本机(C 或 C++)应用程序泄漏的好工具。您可以将它与 Visual Studio 或 WinDbg 一起使用。除了内存泄漏,您还可以检查堆损坏、无效句柄使用情况。将应用程序验证程序与 WinDbg (!analyze -v) 一起使用可以提供很好的洞察力。
【讨论】:
Visual Studio 2019 有一个不错的内存分析工具,它可以在调试时以交互方式使用,也可以通过编程(无需调试)来使用,下面我将在这两种情况下展示一个最小的示例。
主要思想是在进程开始和结束时对堆进行快照,然后比较内存的状态以检测潜在的内存泄漏。
创建以下main.cpp 文件(在新的控制台应用程序中):
#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;
}
然后:
Take snapshot。step over (F10) 几次)并拍摄另一个快照。s (stackoverflow_pb) 存在内存泄漏。您可以通过双击“char[]”对象找到它。上述过程的关键步骤如下图所示:
将代码替换为以下内容:
#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;
}
它做同样的事情,但通过代码,所以你可以将它集成到一个自动构建系统中,函数_CrtMemCheckpoint 拍摄快照,_CrtMemDifference 比较快照的内存状态,如果它们不同,则返回 true。
既然是这种情况,它就会进入条件块并通过几个函数打印有关泄漏的详细信息(请参阅_CrtMemDumpStatistics、_CrtMemDumpAllObjectsSince 和_CrtDumpMemoryLeaks - 后者不需要快照)。
要查看输出,请在最后一行“return 0”中放置一个断点,点击F5 并查看调试控制台。这是输出:
要了解更多信息,请参阅以下链接:
【讨论】:
new[] 和错误的 delete,2. 访问已释放的内存,3. 其他破坏内存的方式,如越界访问等。 4.访问未初始化的内存
_CRTDBG_DELAY_FREE_MEM_DF 标志(参见上面的链接“CRT 调试堆文件”)。
OutputDebugStringW 需要 LPCWSTR,(3 个字符不足以进行编辑,因为其余的答案是完美的!)
/fsanitize=address 现在可以与 x64 和 x86 一起使用,以解决类似的内存问题。 AddressSanitizer
用于跟踪本机 (C++) 内存泄漏的独立工具 (CLI)。在发布模式下运行您的应用程序(PDB 应该可用)并让它一起运行。它会输出所有可疑的调用堆栈及其相关的泄漏大小:
【讨论】:
一个可靠的解决方案是将Address Sanitizer 用于Visual Studio。这是一个跨平台/跨编译器解决方案,因此您获得的知识将转移到gcc and clang。
此工具具有线程清理和一般内存错误检测(释放后使用、双重释放、未初始化使用等)的扩展,但泄漏检测是它的强项之一。您需要 Microsoft 编译器的 /fsanitize=address /Zi 选项,但您可以参考第一篇链接文章,了解如何将其合并到解决方案和更大的项目中(通过 CMake 配置或项目属性调整)
【讨论】: