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

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

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

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

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


当前回答

您可以使用Valgrind工具来检测内存泄漏。

此外,要找到特定函数中的漏洞,请在函数末尾使用exit(0),然后使用Valgrind运行它

`$` valgrind ./your_CPP_program 

其他回答

在应用程序代码中不应该使用“new”或“delete”。相反,应该创建一个使用管理器/工作人员习惯用法的新类型,其中管理器类分配和释放内存,并将所有其他操作转发给工作人员对象。

不幸的是,这比它应该做的要多,因为c++没有“operator .”的重载。如果存在多态,则工作量更大。

但是这样做是值得的,因为这样您就不必担心内存泄漏,这意味着您甚至不需要寻找它们。

您可以在代码中使用一些技术来检测内存泄漏。最常见和最简单的检测方法是,定义一个宏(比如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.

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.

Download Debugging Tools for Windows. Use the gflags utility to turn on user-mode stack traces. Use UMDH to take multiple snapshots of your program's memory. Take a snapshot before memory gets allocated, and take a second snapshot after a point at which you believe that your program has leaked memory. You might want to add pauses or prompts in your program to give you a chance to run UMDH and take the snapshots. Run UMDH again, this time in its mode that does a diff between the two snapshots. It will then generate a report containing the call stacks of suspected memory leaks. Restore your previous gflags settings when you're done.

UMDH会给你比CRT调试堆更多的信息,因为它会监视整个进程的内存分配;它甚至可以告诉您第三方组件是否泄漏。

确保成功释放了所有堆内存。如果您从未在堆上分配内存,则不需要这样做。如果你这样做,计算你malloc内存的次数,并计算你释放内存的次数。