【问题标题】:C++ Microsoft Visual Studio 2017 best and easiest way to detect memory leaks?C++ Microsoft Visual Studio 2017 检测内存泄漏的最佳和最简单的方法?
【发布时间】:2020-05-27 17:01:13
【问题描述】:

目前我有一个解决方案,但我不确定在每种情况下是否都可以。我可以使用此解决方案检查程序中是否存在任何内存泄漏?如果有人可以提供更好的解决方案,请不要犹豫分享答案。谢谢!

我的示例代码在这里:

int *array = new int[5];
delete[] array; //so no memory leaks

//Memory leak check.
if (_CrtDumpMemoryLeaks()) {
    std::cout << "Memory leaks!\n";
}
else {
    std::cout << "No leaks\n";
}

cin.get();
return 0;

【问题讨论】:

  • 有微软调试诊断工具。也许现在它有不同的名字。它使用 callstakcs 创建了非常好的泄漏报告。

标签: c++ memory-leaks


【解决方案1】:

我找到了其他解决方案 - 有人可以同意吗?(来源:https://docs.microsoft.com/en-us/visualstudio/profiling/memory-usage?view=vs-2017

第一步 - 创建 3 个断点。 !!!最后一个断点应该放在返回之后 - 不在行!

第二步 - 开始调试和创建快照。 (诊断工具)

第三步 - 点击第二个快照,查看堆中动态分配的 3 个变量。

第四步 - 点击我们制作的第三个快照 - 所以我们在释放 'a' 指针的内存后拍摄它: delete a;这就是为什么这里的大小只有 8 个字节。 (12 字节 - 我们刚刚发布的 4 字节)

【讨论】:

  • 干得好,但不是解决方案,就查找内存泄漏而言。在真正的程序中,您永远不知道在哪里放置断点以及在哪里预计泄漏。您只确定了内存分配的事实,但尚未确定泄漏的事实。并且没有分配的调用栈。
  • 内存泄漏是由分配的 - 但不是释放的内存引起的?如果我设置了两个断点——一个在入口处,另一个在程序结束处,那么它应该指示取消分配的动态变量。
  • 你说的是小事。您确切地知道在哪里放置断点,从哪里开始,从哪里结束。在真正的程序中你将无法做到。
  • 发现内存泄漏的过程意味着在启动疑似泄漏的功能之前拍摄快照。重复此功能 N 次,并在这 N 次重复后拍摄第二张快照。制作这两个快照之间的内存分配报告。诊断工具应该在快照之间进行差异并报告未释放的内存分配,添加分配的调用堆栈。理想情况下,泄漏 stask 的计数是 N 的倍数,但它不是公理。
  • 您诊断出内存泄漏意味着您拥有完整的调用链,因此您可以在代码中修复它。
【解决方案2】:

在您的情况下,最适合您首先使用的是 CRT 库,并且确实使用了 _CrtDumpMemoryLeaks();,如 Microsoft 文档所述:

_CrtDumpMemoryLeaks 函数确定自程序执行开始后是否发生内存泄漏。

关于您的其他疑问:

但我不确定是否在每种情况下都可以

根据 microsoft 文档,它应该记录整个程序中发生的任何内存泄漏,即使它位于类中或您可能认为的任何地方:

发生内存泄漏时转储调试堆中的所有内存块

也不要忘记#define _DEBUG 标志,如此处提到的:

如果未定义 _DEBUG,则在预处理期间会删除对 _CrtDumpMemoryLeaks 的调用。

但是,如果您正在制作软件,您应该使用 STL 并使用智能指针。

另外你可能有另一种方法来检查某个资源的内存泄漏,我在调试时使用 Visual Studio 提供的内存选项卡,它位于 debug > windows > memory > memory1(注意:您必须处于调试模式才能看到设置)然后在搜索栏中输入array,这样您就可以转到您指向的内存所在的位置,然后您可以直接进入您的程序并查看内存是否被清空。

注意: 如果您想一次直观地监控一个资源,而不是想对每个可能泄漏的资源进行完整转储,则这种方法更有用。

【讨论】:

  • 谢谢!如果我有不同的类具有不同的内存分配 - ..和析构函数,它是否也有效?
  • 没问题!是的,对于 CRT 库,它应该检测到它们(任何时候你分配内存,如文档所述:Dumps all the memory blocks in the debug heap when a memory leak has occurred ),对于我的技术,你只需输入分配内存的指针的名称,它应该将你重定向到它是内存中的虚拟地址。顺便说一句,如果这解决了您的答案,请不要忘记打绿色复选标记:D
  • @Tivi 更新了我的答案并添加了回复:)
  • 谢谢!我目前正在尝试按照您的方式找到如何做到这一点。在 debug > windows...我真的找不到内存,memory1 - 我需要创建断点吗?
  • @Tivi 是的,在你的入口点创建一个断点,然后进入调试,对不起
猜你喜欢
  • 2011-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-27
  • 2020-04-11
相关资源
最近更新 更多