我是Windows平台上的c++程序员。我使用的是Visual Studio 2008。
我通常会在代码中出现内存泄漏。
通常我通过检查代码来发现内存泄漏,但这很麻烦,而且并不总是一种好方法。
因为我买不起付费的内存泄漏检测工具,所以我想让你们建议避免内存泄漏的最佳方法。
我想知道如何程序员可以找到内存泄漏。 是否应该遵循某种标准或过程来确保程序中没有内存泄漏?
我是Windows平台上的c++程序员。我使用的是Visual Studio 2008。
我通常会在代码中出现内存泄漏。
通常我通过检查代码来发现内存泄漏,但这很麻烦,而且并不总是一种好方法。
因为我买不起付费的内存泄漏检测工具,所以我想让你们建议避免内存泄漏的最佳方法。
我想知道如何程序员可以找到内存泄漏。 是否应该遵循某种标准或过程来确保程序中没有内存泄漏?
当前回答
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.
其他回答
除了其他答案中提供的工具和方法之外,静态代码分析工具还可以用于检测内存泄漏(以及其他问题)。 Cppcheck是一个免费的健壮的工具。但是还有很多其他可用的工具。Wikipedia有一个静态代码分析工具列表。
Visual Leak Detector (VLD)是一个免费的、健壮的、开源的Visual c++内存泄漏检测系统。
当您在Visual Studio调试器下运行程序时,Visual Leak Detector将在调试会话结束时输出内存泄漏报告。泄漏报告包括完整的调用堆栈,显示泄漏的内存块是如何分配的。双击调用堆栈中的一行,以跳转到编辑器窗口中的该文件和该行。
如果你只有崩溃转储,你可以使用Windbg !heap -l命令,它将检测泄漏的堆块。最好打开gflags选项:“创建用户模式堆栈跟踪数据库”,然后您将看到内存分配调用堆栈。
MTuner是一个免费的多平台内存分析、泄漏检测和分析工具,支持MSVC、GCC和Clang编译器。功能包括:
基于时间轴的内存使用历史和活动内存块 强大的内存操作过滤基于堆,内存标签,时间范围等。 SDK手动仪表与完整的源代码 通过命令行使用支持持续集成 调用堆栈树和树映射导航 更多。
用户可以通过GCC或Clang cross配置任何软件定位平台 编译器。MTuner内置对Windows、PlayStation 4和PlayStation 3平台的支持。
您可以使用Valgrind工具来检测内存泄漏。
此外,要找到特定函数中的漏洞,请在函数末尾使用exit(0),然后使用Valgrind运行它
`$` valgrind ./your_CPP_program
运行“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调用。