我是Windows平台上的c++程序员。我使用的是Visual Studio 2008。

我通常会在代码中出现内存泄漏。

通常我通过检查代码来发现内存泄漏,但这很麻烦,而且并不总是一种好方法。

因为我买不起付费的内存泄漏检测工具,所以我想让你们建议避免内存泄漏的最佳方法。

我想知道如何程序员可以找到内存泄漏。 是否应该遵循某种标准或过程来确保程序中没有内存泄漏?


当前回答

您可以在代码中使用一些技术来检测内存泄漏。最常见和最简单的检测方法是,定义一个宏(比如DEBUG_NEW),并使用它与预定义的宏(如__FILE__和__LINE__)一起定位代码中的内存泄漏。这些预定义的宏告诉您内存泄漏的文件号和行号。

DEBUG_NEW只是一个宏,通常定义为:

#define DEBUG_NEW new(__FILE__, __LINE__)
#define new DEBUG_NEW

因此,无论在哪里使用new,它都可以跟踪文件和行号,这可以用来定位程序中的内存泄漏。

而__FILE__, __LINE__是预定义的宏,它们分别计算你使用它们的文件名和行号!

阅读下面的文章,它解释了使用DEBUG_NEW和其他有趣的宏的技术,非常漂亮:

一个跨平台的内存泄漏检测器


从Wikpedia,

Debug_new refers to a technique in C++ to overload and/or redefine operator new and operator delete in order to intercept the memory allocation and deallocation calls, and thus debug a program for memory usage. It often involves defining a macro named DEBUG_NEW, and makes new become something like new(_FILE_, _LINE_) to record the file/line information on allocation. Microsoft Visual C++ uses this technique in its Microsoft Foundation Classes. There are some ways to extend this method to avoid using macro redefinition while still able to display the file/line information on some platforms. There are many inherent limitations to this method. It applies only to C++, and cannot catch memory leaks by C functions like malloc. However, it can be very simple to use and also very fast, when compared to some more complete memory debugger solutions.

其他回答

运行“Valgrind”可以:

1)帮助识别内存泄漏-显示您有多少内存泄漏,并指出代码中泄漏内存分配的行。

2)指出错误的释放内存的尝试(例如不正确的delete调用)

“Valgrind”使用说明

1)在这里获得valgrind。

2)使用-g标志编译代码

3)在shell中运行:

valgrind --leak-check=yes myprog arg1 arg2

其中"myprog"是你编译的程序,arg1, arg2是你程序的参数。

4)结果是一个调用malloc/new的列表,没有后续调用free delete。

例如:

==4230==    at 0x1B977DD0: malloc (vg_replace_malloc.c:136)

==4230==    by 0x804990F: main (example.c:6)

告诉您在哪一行(未释放的)调用了malloc。

正如其他人指出的那样,确保对于每个新的/malloc调用,都有一个后续的delete/free调用。

Visual Leak Detector (VLD)是一个免费的、健壮的、开源的Visual c++内存泄漏检测系统。

当您在Visual Studio调试器下运行程序时,Visual Leak Detector将在调试会话结束时输出内存泄漏报告。泄漏报告包括完整的调用堆栈,显示泄漏的内存块是如何分配的。双击调用堆栈中的一行,以跳转到编辑器窗口中的该文件和该行。

如果你只有崩溃转储,你可以使用Windbg !heap -l命令,它将检测泄漏的堆块。最好打开gflags选项:“创建用户模式堆栈跟踪数据库”,然后您将看到内存分配调用堆栈。

Search your code for occurrences of new, and make sure that they all occur within a constructor with a matching delete in a destructor. Make sure that this is the only possibly throwing operation in that constructor. A simple way to do this is to wrap all pointers in std::auto_ptr, or boost::scoped_ptr (depending on whether or not you need move semantics). For all future code just ensure that every resource is owned by an object that cleans up the resource in its destructor. If you need move semantics then you can upgrade to a compiler that supports r-value references (VS2010 does I believe) and create move constructors. If you don't want to do that then you can use a variety of tricky techniques involving conscientious usage of swap, or try the Boost.Move library.

在visual studio中,有一个内置的内存泄漏检测器,称为C运行时库。当主函数返回后程序退出时,CRT将检查应用程序的调试堆。如果在调试堆上仍然分配了任何块,那么就存在内存泄漏。 本论坛讨论了在C/ c++中避免内存泄漏的一些方法。

有一些著名的编程技术可以帮助您将内存泄漏的风险降至最低:

if you have to do your own dynamic memory allocation, write new and delete always pairwise, and make sure the allocation/deallocation code is called pairwise avoid dynamic memory allocation if you can. For example, use vector<T> t whereever possible instead of T* t = new T[size] use "smart pointers" like boost smart pointers (http://www.boost.org/doc/libs/1_46_1/libs/smart_ptr/smart_ptr.htm) my personal favorite: make sure you have understood the concept of ownership of a pointer, and make sure that everywhere where you use pointers, you know which code entity is the owner learn which constructors / assignment operators are automatically created by the C++ compiler, and what that means if you have class that owns a pointer (or what that means if you have a class that contains a pointer to an object it does not own).