当前位置:  开发笔记 > 编程语言 > 正文

如何检测/避免(非托管)代码中的内存泄漏?

如何解决《如何检测/避免(非托管)代码中的内存泄漏?》经验,为你挑选了8个好方法。

在非托管C/C++代码中,检测内存泄漏的最佳实践是什么?和编码指南,以避免?(好像就这么简单;)

过去我们使用了一些愚蠢的方法:每次内存分配调用都有一个计数器增量,而在释放时减少.在程序结束时,计数器值应为零.

我知道这不是一个很好的方式,有一些捕获.(例如,如果释放由平台API调用分配的内存,则分配计数将与您的释放计数不完全匹配.当然,我们在调用分配内存的API调用时递增计数器.)

我期待您的经验,建议和一些简化此工具的工具参考.



1> Jordi Bunste..:

如果你的C/C++代码可以移植到*nix,那么很少有东西比Valgrind好.



2> Dusty Campbe..:

如果您使用的是Visual Studio,Microsoft提供了一些有用的功能来检测和调试内存泄漏.

我将从这篇文章开始:https: //msdn.microsoft.com/en-us/library/x98tx3cf(v = vs.140).aspx

以下是这些文章的快速摘要.首先,包括以下标题:

#define _CRTDBG_MAP_ALLOC
#include 
#include 

然后你需要在你的程序退出时调用它:

_CrtDumpMemoryLeaks();

或者,如果您的程序每次都不在同一个地方退出,您可以在程序开头调用它:

_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );

现在,当程序退出所有未自由的分配时,将在输出窗口中打印它们分配的文件和分配事件.

此策略适用于大多数程序.但是,在某些情况下变得困难或不可能.使用在启动时进行一些初始化的第三方库可能会导致其他对象出现在内存转储中,并且可能难以跟踪泄漏.此外,如果您的任何类具有与任何内存分配例程(例如malloc)同名的成员,则CRT调试宏将导致问题.

在上面引用的MSDN链接中解释的其他技术也可以使用.


@Zach:实际上你也可以使用它(对于你自己编译的任何代码,无论如何) - 请参阅http://social.msdn.microsoft.com/forums/en-US/vcgeneral/thread/5a98b72e中的接受答案-c927-4f4b-9441-8a73575dfb10 /

3> Leon Timmerm..:

在C++中:使用RAII.智能指针一样std::unique_ptr,std::shared_ptr,std::weak_ptr是你的朋友.


只有你错误地使用它们,但我应该承认,对于std :: auto_ptr使用它不正确是非常容易的.
至少std :: auto_ptr和boost :: shared_ptr仍然容易泄漏.
虽然这是编码标准的好建议,但它没有回答这个问题.即使使用shared_ptr也可能导致循环依赖的泄漏.并且您可以通过无限制的缓存策略进行"泄漏",这些策略甚至适用于垃圾收集语言.

4> Huppie..:

作为C++开发人员,这里有一些简单的指导原则:

    仅在绝对必要时使用指针

    如果你需要一个指针,双检如果一个智能指针是一种可能性

    使用GRASP Creator模式.

至于个人内存泄漏的检测我总是使用Visual Leak Detector并发现它非常有用.


Visual Leak Detectore迁至新网站http://vld.codeplex.com/

5> Skizz..:

我已经使用DevStudio太多年了,我总是惊讶于有多少程序员不了解调试运行时库中可用的内存分析工具.以下是一些入门链接:

跟踪堆分配请求 - 特别是有关唯一分配请求号的部分

_CrtSetDbgFlag

_CrtSetBreakAlloc

当然,如果您不使用DevStudio,那么这将不会特别有用.



6> Tal..:

我很惊讶没有人提到用于Windows操作系统的DebugDiag.
它适用于发布版本,甚至适用于客户站点.
(您只需要保留发布版本的PDB,并配置DebugDiag以使用Microsoft公共符号服务器)


链接不再有效,请尝试此处获取文档:http://support.microsoft.com/kb/2580960并在此处下载:http://www.microsoft.com/en-us/download/details.aspx?id = 26798

7> Serge..:

调试模式下的Microsoft VC++显示内存泄漏,但它没有显示泄漏的位置.

如果你正在使用C++,你总是可以避免明确地使用新的:你在你的工具库中有vector(string,auto_ptr预先C++ 11; unique_ptr在C++ 11中替换),unique_ptr(C++ 11)和shared_ptr(C++ 11).

当new不可避免时,尝试将其隐藏在构造函数中(并在析构函数中隐藏delete); 同样适用于第三方API.



8> Hernán..:

Visual Leak Detector是一个非常好的工具,尽管它不支持VC9运行时的调用(例如MSVCR90D.DLL).

推荐阅读
喜生-Da
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有