How do you detect/avoid Memory leaks in your (Unmanaged) code?

c++ c memory-leaks

152968 观看

29回复

29595 作者的声誉

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 ;)

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.)

I am expecting your experiences, suggestions and maybe some references to tools which simplify this.

作者: prakash 的来源 发布者: 2008 年 9 月 5 日

回应 29


3

10623 作者的声誉

从来没有用过它,但我的C朋友告诉我Purify

作者: Iain Holder 发布者: 2008 年 9 月 5 日

4

137772 作者的声誉

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.

作者: Paul Tomblin 发布者: 2008 年 9 月 5 日

77

4575 作者的声誉

If your C/C++ code is portable to *nix, few things are better than Valgrind.

作者: Jordi Bunster 发布者: 2008 年 9 月 5 日

1

97401 作者的声誉

在摩托罗拉手机操作系统上工作时,我们劫持了内存分配库,以观察所有内存分配。它有助于在内存分配方面找到很多问题。由于预防比固化更好,我建议使用像KlockworkPC-Lint这样的静态分析工具

作者: aku 发布者: 2008 年 9 月 5 日

2

29545 作者的声誉

您是通过插入自己的记录调用的系统调用函数来计算alloc和frees,然后将调用传递给实际函数吗?

这是您可以跟踪源自您尚未编写的代码的调用的唯一方法。

看一下ld.so的手册页。或者在某些系统上使用ld.so.1。

也可以在Google LD_PRELOAD上找到一些有趣的文章,在www.itworld.com上解释这项技术。

作者: Rob Wells 发布者: 2008 年 9 月 5 日

28

8915 作者的声誉

As a C++ Developer here's some simply guidelines:

  1. Use pointers only when absolutely necessary
  2. If you need a pointer, doublecheck if a SmartPointer is a possibility
  3. Use the GRASP Creator pattern.

As for the detection of memory leaks personally I've always used Visual Leak Detector and find it to be very useful.

作者: Huppie 发布者: 2008 年 9 月 5 日

7

5801 作者的声誉

Microsoft VC++ in debug mode shows memory leaks, although it doesn't show where your leaks are.

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.

When new is unavoidable, try to hide it in a constructor (and hide delete in a destructor); the same works for 3rd party APIs.

作者: Serge 发布者: 2008 年 9 月 5 日

3

22271 作者的声誉

如果您使用的是Visual Studio,那么查看Bounds Checker可能是值得的。它不是免费的,但它在我的代码中发现泄漏非常有帮助。它不仅会造成内存泄漏,还会造成GDI资源泄漏,WinAPI使用错误以及其他问题。它甚至可以显示泄漏内存的初始化位置,从而更容易追踪泄漏。

作者: Herms 发布者: 2008 年 9 月 5 日

4

17039 作者的声誉

If you're using MS VC++, I can highly recommend this free tool from the codeproject: leakfinder by Jochen Kalmbach.

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.

Rational(现在由IBM拥有)PurifyPlus以类似的方式说明泄漏,但我发现泄漏探测器工具实际上更容易使用,其奖金不花费数千美元!

作者: John Sibly 发布者: 2008 年 9 月 5 日

16

43297 作者的声誉

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:

Tracking Heap Allocation Requests - specifically the section on Unique Allocation Request Numbers

_CrtSetDbgFlag

_CrtSetBreakAlloc

Of course, if you're not using DevStudio then this won't be particularly helpful.

作者: Skizz 发布者: 2008 年 9 月 5 日

1

1233 作者的声誉

至少对于MS VC ++,C Runtime库有几个我以前发现有用的函数。检查MSDN帮助以获取这些_Crt*功能。

作者: Dan Shield 发布者: 2008 年 9 月 5 日

37

27886 作者的声誉

In C++: use RAII. Smart pointers like std::unique_ptr, std::shared_ptr, std::weak_ptr are your friends.

作者: Leon Timmermans 发布者: 2008 年 9 月 5 日

0

987 作者的声誉

Valgrind是Linux的不错选择。在MacOS X下,您可以启用MallocDebug库,该库有几个用于调试内存分配问题的选项(请参阅malloc联机帮助页,“ENVIRONMENT”部分有相关详细信息)。OS X SDK还包括一个名为MallocDebug的工具(通常安装在/ Developer / Applications / Performance Tools /中),可以帮助您监控使用情况和泄漏情况。

作者: jbl 发布者: 2008 年 9 月 5 日

2

8594 作者的声誉

我认为这个问题没有简单的答案。您如何真正接近此解决方案取决于您的要求。您需要跨平台解决方案吗?您使用new / delete或malloc / free(或两者)吗?您是否真的在寻找“泄漏”或者您是否想要更好的保护,例如检测缓冲区溢出(或欠载)?

如果您正在Windows端工作,MS调试运行时库具有一些基本的调试检测功能,而另一个已经指出,有几个包装器可以包含在您的源中以帮助进行泄漏检测。找到一个可以同时使用new / delete和malloc / free的包显然可以提供更大的灵活性。

我不太了解unix方提供帮助,尽管其他人也有。

但是,除了泄漏检测之外,还有通过缓冲区溢出(或欠载)检测内存损坏的概念。我认为这种类型的调试功能比普通的泄漏检测更难。如果使用C ++对象,这种类型的系统也会变得更加复杂,因为可以以不同的方式删除多态类,从而导致确定正在删除的真正基指针的棘手问题。我知道没有一个好的“免费”系统能够为超支提供良好的保护。我们编写了一个系统(跨平台),发现它非常具有挑战性。

作者: Mark 发布者: 2008 年 9 月 5 日

2

3966 作者的声誉

我想提供过去曾经使用的东西:一个基本的泄漏检查器,它是源级别并且相当自动化。我之所以放弃它有三个原因:

  1. 你可能会发现它很有用。

  2. 虽然它有点夸张,但我不会让那个让我感到尴尬。

  3. 尽管它与一些win32挂钩有关,但这应该很容易缓解。

有些事情在使用时必须小心:不要做任何需要依赖new于底层代码的事情,要注意泄漏检查可能会在misscheck.cpp顶部错过的情况,并意识到如果你转向在(并修复任何问题)执行图像转储的代码,您可能会生成一个巨大的文件。

该设计旨在允许您打开和关闭检查器,而无需重新编译包含其标题的所有内容。在您要跟踪检查和重建一次的地方包含leakcheck.h。此后,使用或不使用LEAKCHECK #define'd编译leakcheck.cpp,然后重新链接以打开和关闭它。包括unleakcheck.h将在文件中本地关闭它。提供了两个宏:当遍历分配不包含leakcheck.h的代码时,CLEARALLOCINFO()将避免报告相同的文件和行。ALLOCFENCE()只是在生成的报告中删除一行而不进行任何分配。

再次,请意识到我有一段时间没有使用它,你可能需要稍微使用它。我正在放弃它来说明这个想法。如果事实证明有足够的兴趣,我愿意做一个例子,更新流程中的代码,并用更好的东西替换下面URL的内容,其中包括一个体面的语法颜色列表。

你可以在这里找到它:http//www.cse.ucsd.edu/~tkammeye/leakcheck.html

作者: Thomas Kammeyer 发布者: 2008 年 9 月 5 日

0

14619 作者的声誉

检测:

调试CRT

避免:

智能指针,boehm GC

作者: DrPizza 发布者: 2008 年 9 月 6 日

64

2633 作者的声誉

If you are using Visual Studio, Microsoft provides some useful functions for detecting and debugging memory leaks.

I would start with this article: 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.

There are other techniques explained in the MSDN link referenced above that could be used as well.

作者: Dusty Campbell 发布者: 2008 年 9 月 8 日

1

8003 作者的声誉

Paul Nettle的mmgr是我长期以来最喜欢的工具。在源文件中包含mmgr.h,定义TEST_MEMORY,它会提供一个文本文件,其中包含在应用程序运行期间发生的内存问题。

作者: Josh Matthews 发布者: 2008 年 9 月 13 日

2

1518 作者的声誉

对于Linux:尝试Google Perftools

有很多工具可以进行类似的alloc / free计数,Goolge Perftools的优点:

  • 相当快(与valgrind相比:非常快)
  • 附带精美的图形显示结果
  • 还有其他有用的功能:cpu-profiling,内存使用情况分析......
作者: Weidenrinde 发布者: 2008 年 9 月 16 日

1

1518 作者的声誉

一般编码指南:

  • 资源应该在分配它们的同一“层”(函数/类/库)中释放。
  • 如果这不可能,请尝试使用一些自动释放(boost共享指针......)
作者: Weidenrinde 发布者: 2008 年 9 月 16 日

2

7162 作者的声誉

防止泄漏的最佳方法是程序结构,它最大限度地减少了malloc的使用。这不仅从编程角度来看是好的,而且还提高了性能和可维护性。我不是在谈论使用其他东西代替malloc,而是在重用对象和保持非常明确的选项卡来传递所有被传递的对象,而不是像通常习惯于使用垃圾收集器的语言那样分配。像Java一样。

例如,我工作的程序有一堆表示图像数据的框架对象。每个帧对象都有子数据,帧的析构函数可以释放。程序保留所有已分配帧的列表,当需要新帧时,检查未使用的帧对象列表,以查看它是否可以重用现有帧,而不是分配新帧。在关闭时,它只是遍历列表,释放所有内容。

作者: Dark Shikari 发布者: 2008 年 9 月 16 日

2

359 作者的声誉

我建议使用来自软件验证的Memory Validator。该工具证明了它非常有用,可以帮助我跟踪内存泄漏并改进我正在处理的应用程序的内存管理。

一个非常完整和快速的工具。

作者: Fabien Hure 发布者: 2008 年 9 月 21 日

10

1358 作者的声誉

I’m amazed no one mentioned DebugDiag for 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)

作者: Tal 发布者: 2008 年 10 月 12 日

0

6918 作者的声誉

一个不错的malloc,calloc和reallloc替换是rmdebug,它使用起来非常简单。那么valgrind要快得多,所以你可以广泛地测试你的代码。当然它有一些缺点,一旦你发现泄漏,你可能仍然需要使用valgrind找到泄漏出现的位置,你只能测试你直接做的mallocs。如果因为你使用错误而导致lib泄漏,rmdebug将无法找到它。

http://www.hexco.de/rmdebug/

作者: quinmars 发布者: 2008 年 10 月 12 日

7

3431 作者的声誉

Visual Leak Detector is a very good tool, altough it does not supports the calls on VC9 runtimes (MSVCR90D.DLL for example).

作者: Hernán 发布者: 2008 年 12 月 22 日

-1

2212 作者的声誉

Mtrace似乎是linux的标准内置版本。步骤是:

  1. 在bash中设置环境变量MALLOC_TRACE
    MALLOC_TRACE = / tmp / mtrace.dat
    export MALLOC_TRACE;
  2. #include 添加到主源文件的顶部
  3. 添加mtrace(); 在main和muntrace()的开头; 在底部(在返回声明之前)
  4. 使用-g开关编译程序以获取调试信息
  5. 运行你的程序
  6. 使用
    mtrace显示泄漏信息your_prog_exe_name /tmp/mtrace.dat
    (我必须先在我的fedora系统上安装mtrace perl脚本,并使用yum install glibc_utils   )
作者: paperhorse 发布者: 2009 年 6 月 16 日

1

3844 作者的声誉

内存调试工具非常值得用金,但多年来我发现可以使用两个简单的想法来防止大多数内存/资源泄漏被编码。

  1. 在为要分配的资源编写获取代码后立即写入发布代码。使用这种方法更难以“忘记”,并且在某种意义上迫使人们认真考虑前期使用的资源的生命周期而不是放在一边。

  2. 尽可能使用return作为陪练。分配的内容应尽可能在一个地方释放。获取资源和发布之间的条件路径应尽可能简单明了。

作者: Einstein 发布者: 2009 年 6 月 16 日

1

3270 作者的声誉

在这个列表的顶部(当我读它时)是valgrind。如果您能够在测试系统上重现泄漏,Valgrind非常出色。我用它取得了巨大的成功。

如果您刚刚注意到生产系统现在正在泄漏并且您不知道如何在测试中重现它,该怎么办?在生产系统的状态中捕获了一些错误的证据,它可能足以提供问题所在的洞察力,以便您可以重现它。

这就是蒙特卡罗采样的地方。阅读Raymond Chen的博客文章“穷人识别内存泄漏的方法”,然后查看我的实现(假设Linux,仅在x86和x86-64上测试)

http://github.com/tialaramex/leakdice/tree/master

作者: tialaramex 发布者: 2009 年 6 月 20 日

0

1038 作者的声誉

大多数内存分析器将我的大型复杂Windows应用程序放慢到结果无用的程度。有一种工具适用于在我的应用程序中查找泄漏:UMDH - http://msdn.microsoft.com/en-us/library/ff560206%28VS.85%29.aspx

作者: Sean 发布者: 2010 年 12 月 2 日
32x32