C++ 您如何检测/避免(非托管)代码中的内存泄漏?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/45627/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do you detect/avoid Memory leaks in your (Unmanaged) code?
提问by prakash
In unmanaged C/C++ code, what are the best practices to detect memory leaks? And coding guidelines to avoid? (As if it's that simple ;)
在非托管 C/C++ 代码中,检测内存泄漏的最佳做法是什么?以及要避免的编码指南?(好像就这么简单;)
We have used a bit of a silly way in the past: having a counter increment for every memory allocation call and decrement while freeing. At the end of the program, the counter value should be zero.
过去我们使用了一些愚蠢的方法:每次内存分配调用都有一个计数器递增,并在释放时递减。在程序结束时,计数器值应为零。
I know this is not a great way and there are a few catches. (For instance, if you are freeing memory which was allocated by a platform API call, your allocation count will not exactly match your freeing count. Of course, then we incremented the counter when calling API calls that allocated memory.)
我知道这不是一个好方法,并且有一些问题。(例如,如果您正在释放由平台 API 调用分配的内存,则您的分配计数将与您的释放计数不完全匹配。当然,我们在调用分配内存的 API 调用时增加了计数器。)
I am expecting your experiences, suggestions and maybe some references to tools which simplify this.
我期待您的经验、建议以及可能对简化此操作的工具的一些参考。
回答by Jordi Bunster
回答by Dusty Campbell
If you are using Visual Studio, Microsoft provides some useful functions for detecting and debugging memory leaks.
如果您使用的是 Visual Studio,Microsoft 提供了一些有用的功能来检测和调试内存泄漏。
I would start with this article: https://msdn.microsoft.com/en-us/library/x98tx3cf(v=vs.140).aspx
我将从这篇文章开始:https: //msdn.microsoft.com/en-us/library/x98tx3cf(v=vs.140).aspx
Here is the quick summary of those articles. First, include these headers:
以下是这些文章的快速摘要。首先,包括这些标题:
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
Then you need to call this when your program exits:
然后你需要在程序退出时调用它:
_CrtDumpMemoryLeaks();
Alternatively, if your program does not exit in the same place every time, you can call this at the start of your program:
或者,如果您的程序不是每次都在同一个地方退出,您可以在程序开始时调用它:
_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
Now when the program exits all the allocations that were not free'd will be printed in the Output Window along with the file they were allocated in and the allocation occurrence.
现在,当程序退出时,所有未被释放的分配将与它们被分配的文件和分配发生一起打印在输出窗口中。
This strategy works for most programs. However, it becomes difficult or impossible in certain cases. Using third party libraries that do some initialization on startup may cause other objects to appear in the memory dump and can make tracking down your leaks difficult. Also, if any of your classes have members with the same name as any of the memory allocation routines( such as malloc ), the CRT debug macros will cause problems.
此策略适用于大多数程序。但是,在某些情况下,这变得困难或不可能。使用在启动时进行一些初始化的第三方库可能会导致其他对象出现在内存转储中,并使跟踪泄漏变得困难。此外,如果您的任何类具有与任何内存分配例程(例如 malloc )同名的成员,则 CRT 调试宏将导致问题。
There are other techniques explained in the MSDN link referenced above that could be used as well.
上面引用的 MSDN 链接中解释了其他技术也可以使用。
回答by Leon Timmermans
In C++: use RAII. Smart pointers like std::unique_ptr
, std::shared_ptr
, std::weak_ptr
are your friends.
在 C++ 中:使用 RAII。智能指针一样std::unique_ptr
,std::shared_ptr
,std::weak_ptr
是你的朋友。
回答by Huppie
As a C++ Developer here's some simply guidelines:
作为 C++ 开发人员,这里有一些简单的指导方针:
- Use pointers only when absolutely necessary
- If you need a pointer, doublecheck if a SmartPointeris a possibility
- Use the GRASP Creatorpattern.
As for the detection of memory leaks personally I've always used Visual Leak Detectorand find it to be very useful.
至于检测内存泄漏,我个人一直使用Visual Leak Detector,发现它非常有用。
回答by Skizz
I've been using DevStudio for far too many years now and it always amazes me just how many programmers don't know about the memory analysis tools that are available in the debug run time libraries. Here's a few links to get started with:
我已经使用 DevStudio 太多年了,它总是让我惊讶有多少程序员不知道调试运行时库中可用的内存分析工具。以下是一些入门链接:
Tracking Heap Allocation Requests- specifically the section on Unique Allocation Request Numbers
跟踪堆分配请求- 特别是关于唯一分配请求编号的部分
Of course, if you're not using DevStudio then this won't be particularly helpful.
当然,如果您不使用 DevStudio,那么这不会特别有用。
回答by Tal
I'm amazed no one mentioned DebugDiagfor Windows OS.
It works on release builds, and even at the customer site.
(You just need to keep your release version PDBs, and configure DebugDiag to use Microsoft public symbol server)
我很惊讶没有人提到Windows 操作系统的DebugDiag。
它适用于发布版本,甚至适用于客户站点。
(您只需要保留您的发布版本 PDB,并将 DebugDiag 配置为使用 Microsoft 公共符号服务器)
回答by Hernán
Visual Leak Detector is a very good tool, altough it does not supports the calls on VC9 runtimes (MSVCR90D.DLL for example).
Visual Leak Detector 是一个非常好的工具,尽管它不支持对 VC9 运行时的调用(例如 MSVCR90D.DLL)。
回答by Serge
Microsoft VC++ in debug mode shows memory leaks, although it doesn't show where your leaks are.
调试模式下的 Microsoft VC++ 显示内存泄漏,尽管它没有显示泄漏的位置。
If you are using C++ you can always avoid using new explicitly: you have vector
, string
, auto_ptr
(pre C++11; replaced by unique_ptr
in C++11), unique_ptr
(C++11) and shared_ptr
(C++11) in your arsenal.
如果您使用 C++,您总是可以避免显式使用 new:您的武器库中有vector
, string
, auto_ptr
(pre C++11;unique_ptr
在 C++11 中被替换), unique_ptr
(C++11) 和shared_ptr
(C++11)。
When new is unavoidable, try to hide it in a constructor (and hide delete in a destructor); the same works for 3rd party APIs.
当 new 不可避免时,尝试将其隐藏在构造函数中(并在析构函数中隐藏 delete);这同样适用于 3rd 方 API。
回答by Paul Tomblin
There are various replacement "malloc" libraries out there that will allow you to call a function at the end and it will tell you about all the unfreed memory, and in many cases, who malloced (or new'ed) it in the first place.
有各种替代的“malloc”库,它们允许你在最后调用一个函数,它会告诉你所有未释放的内存,在许多情况下,谁首先分配(或更新)它.
回答by John Sibly
If you're using MS VC++, I can highly recommend this free tool from the codeproject: leakfinderby Jochen Kalmbach.
如果您使用的是 MS VC++,我强烈推荐代码项目中的这个免费工具: Jochen Kalmbach 的leakfinder。
You simply add the class to your project, and call
您只需将该类添加到您的项目中,然后调用
InitAllocCheck(ACOutput_XML)
DeInitAllocCheck()
before and after the code you want to check for leaks.
在要检查泄漏的代码之前和之后。
Once you've build and run the code, Jochen provides a neat GUI tool where you can load the resulting .xmlleaks file, and navigate through the call stack where each leak was generated to hunt down the offending line of code.
构建并运行代码后,Jochen 提供了一个简洁的 GUI 工具,您可以在其中加载生成的 .xmlleaks 文件,并浏览生成每个泄漏的调用堆栈以查找有问题的代码行。
Rational's (now owned by IBM) PurifyPlus illustrates leaks in a similar fashion, but I find the leakfinder tool actually easier to use, with the bonus of it not costing several thousand dollars!
Rational(现在由 IBM 拥有)的 PurifyPlus 以类似的方式说明了泄漏,但我发现泄漏查找工具实际上更易于使用,而且它的好处是不花费数千美元!