在非托管C/C++代码中,检测内存泄漏的最佳实践是什么?和编码指南,以避免?(好像就这么简单;)
过去我们使用了一些愚蠢的方法:每次内存分配调用都有一个计数器增量,而在释放时减少.在程序结束时,计数器值应为零.
我知道这不是一个很好的方式,有一些捕获.(例如,如果释放由平台API调用分配的内存,则分配计数将与您的释放计数不完全匹配.当然,我们在调用分配内存的API调用时递增计数器.)
我期待您的经验,建议和一些简化此工具的工具参考.
如果你的C/C++代码可以移植到*nix,那么很少有东西比Valgrind好.
如果您使用的是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链接中解释的其他技术也可以使用.
在C++中:使用RAII.智能指针一样std::unique_ptr
,std::shared_ptr
,std::weak_ptr
是你的朋友.
作为C++开发人员,这里有一些简单的指导原则:
仅在绝对必要时使用指针
如果你需要一个指针,双检如果一个智能指针是一种可能性
使用GRASP Creator模式.
至于个人内存泄漏的检测我总是使用Visual Leak Detector并发现它非常有用.
我已经使用DevStudio太多年了,我总是惊讶于有多少程序员不了解调试运行时库中可用的内存分析工具.以下是一些入门链接:
跟踪堆分配请求 - 特别是有关唯一分配请求号的部分
_CrtSetDbgFlag
_CrtSetBreakAlloc
当然,如果您不使用DevStudio,那么这将不会特别有用.
我很惊讶没有人提到用于Windows操作系统的DebugDiag.
它适用于发布版本,甚至适用于客户站点.
(您只需要保留发布版本的PDB,并配置DebugDiag以使用Microsoft公共符号服务器)
调试模式下的Microsoft VC++显示内存泄漏,但它没有显示泄漏的位置.
如果你正在使用C++,你总是可以避免明确地使用新的:你在你的工具库中有vector
(string
,auto_ptr
预先C++ 11; unique_ptr
在C++ 11中替换),unique_ptr
(C++ 11)和shared_ptr
(C++ 11).
当new不可避免时,尝试将其隐藏在构造函数中(并在析构函数中隐藏delete); 同样适用于第三方API.
Visual Leak Detector是一个非常好的工具,尽管它不支持VC9运行时的调用(例如MSVCR90D.DLL).