C/C++内存泄漏及检测
作者:网络转载 发布时间:[ 2015/4/1 14:39:18 ] 推荐标签:C++ 内存 泄露 检测
顾名思义,_CrtMemDifference 比较两个内存状态(s1 和 s2),生成这两个状态之间差异的结果(s3)。 在程序的开始和结尾放置 _CrtMemCheckpoint 调用,并使用_CrtMemDifference 比较结果,是检查内存泄漏的另一种方法。 如果检测到泄漏,则可以使用 _CrtMemCheckpoint 调用通过二进制搜索技术来划分程序和定位泄漏。
如上面的例子程序我们可以这样来定位确切的调用GetMemory的地方:
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#include <iostream>
using namespace std;
_CrtMemState s1, s2, s3;
void GetMemory(char *p, int num)
{
p = (char*)malloc(sizeof(char) * num);
}
int main(int argc,char** argv)
{
_CrtMemCheckpoint( &s1 );
char *str = NULL;
GetMemory(str, 100);
_CrtMemCheckpoint( &s2 );
if ( _CrtMemDifference( &s3, &s1, &s2) )
_CrtMemDumpStatistics( &s3 );
cout<<"Memory leak test!"<<endl;
_CrtDumpMemoryLeaks();
return 0;
}
调试时,程序输出如下结果:
这说明在s1和s2之间存在内存泄漏!!!如果GetMemory不是在s1和s2之间调用,那么不会有信息输出。
3、Linux平台下的内存泄漏检测
在上面我们介绍了,vs中在代码中“包含crtdbg.h,将 malloc 和 free 函数映射到它们的调试版本,即 _malloc_dbg 和 _free_dbg,这两个函数将跟踪内存分配和释放。 此映射只在调试版本(在其中定义了_DEBUG)中发生。 发布版本使用普通的 malloc 和 free 函数。”即为malloc和free做了钩子,用于记录内存分配信息。
Linux下面也有原理相同的方法——mtrace,http://en.wikipedia.org/wiki/Mtrace。方法类似,我这不具体描述,参加给出的链接。这节我主要介绍一个非常强大的工具valgrind。如下图所示:
如上图所示知道:
==6118== 100 bytes in 1 blocks are definitely lost in loss record 1 of 1
==6118== at 0x4024F20: malloc (vg_replace_malloc.c:236)
==6118== by 0x8048724: GetMemory(char*, int) (in /home/netsky/workspace/a.out)
==6118== by 0x804874E: main (in /home/netsky/workspace/a.out)
是在main中调用了GetMemory导致的内存泄漏,GetMemory中是调用了malloc导致泄漏了100字节的内存。
Things to notice:
? There is a lot of information in each error message; read it carefully.
? The 6118 is the process ID; it’s usually unimportant.
? The ?rst line ("Heap Summary") tells you what kind of error it is.
? Below the ?rst line is a stack trace telling you where the problem occurred. Stack traces can get quite large, and be
confusing, especially if you are using the C++ STL. Reading them from the bottom up can help.
? The code addresses (eg. 0x4024F20) are usually unimportant, but occasionally crucial for tracking down weirder
bugs.
The stack trace tells you where the leaked memory was allocated. Memcheck cannot tell you why the memory leaked,
unfortunately. (Ignore the "vg_replace_malloc.c", that’s an implementation detail.)
There are several kinds of leaks; the two most important categories are:
? "de?nitely lost": your program is leaking memory -- ?x it!
? "probably lost": your program is leaking memory, unless you’re doing funny things with pointers (such as moving
them to point to the middle of a heap block)
Valgrind的使用请见手册http://valgrind.org/docs/manual/manual.html。
4、总结
其实内存泄漏的原因可以概括为:调用了malloc/new等内存申请的操作,但缺少了对应的free/delete,总之是,malloc/new比free/delete的数量多。我们在编程时需要注意这点,保证每个malloc都有对应的free,每个new都有对应的deleted!!!平时要养成这样一个好的习惯。
要避免内存泄漏可以总结为以下几点:
程序员要养成良好习惯,保证malloc/new和free/delete匹配;
检测内存泄漏的关键原理是,检查malloc/new和free/delete是否匹配,一些工具也是这个原理。要做到这点,是利用宏或者钩子,在用户程序与运行库之间加了一层,用于记录内存分配情况。
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11