-
1、内存泄漏简介 -
2、Windows平台下的内存泄漏检测 -
2.1、检测是否存在内存泄漏问题 -
2.2、定位具体的内存泄漏地方 -
3、Linux平台下的内存泄漏检测 -
4、总结
1、内存泄漏简介及后果
-
程序运行后置之不理,并且随着时间的流失消耗越来越多的内存(比如服务器上的后台任务,尤其是嵌入式系统中的后台任务,这些任务可能被运行后很多年内都置之不理); -
新的内存被频繁地分配,比如当显示电脑游戏或动画视频画面时; -
程序能够请求未被释放的内存(比如共享内存),甚至是在程序终止的时候; -
泄漏在操作系统内部发生; -
泄漏在系统关键驱动中发生; -
内存非常有限,比如在嵌入式系统或便携设备中; -
当运行于一个终止时内存并不自动释放的操作系统(比如AmigaOS)之上,而且一旦丢失只能通过重启来恢复。
using namespace std;
void GetMemory(char *p, int num)
{
p = (char*)malloc(sizeof(char) * num);//使用new也能够检测出来
}
int main(int argc,char** argv)
{
char *str = NULL;
GetMemory(str, 100);
cout<<"Memory leak test!"<<endl;
//如果main中存在while循环调用GetMemory
//那么问题将变得很严重
//while(1){GetMemory(...);}
return 0;
}
2、Windows平台下的内存泄漏检测
2.1、检测是否存在内存泄漏问题
-
STEP1,在程序中包括以下语句:(#include 语句必须采用上文所示顺序。如果更改了顺序,所使用的函数可能无法正常工作。)
-
STEP2, 在添加了上述语句之后,可以通过在程序中包括以下语句(通常应恰好放在程序退出位置之前)来转储内存泄漏信息:
|
_CrtDumpMemoryLeaks(); |
using namespace std;
void GetMemory(char *p, int num)
{
p = (char*)malloc(sizeof(char) * num);
}
int main(int argc,char** argv)
{
char *str = NULL;
GetMemory(str, 100);
cout<<"Memory leak test!"<<endl;
_CrtDumpMemoryLeaks();
return 0;
}
-
内存分配编号(在大括号内)。 -
块类型(普通、客户端或 CRT)。
“普通块”是由程序分配的普通内存。 “客户端块”是由 MFC 程序用于需要析构函数的对象的特殊类型内存块。MFC new 操作根据正在创建的对象的需要创建普通块或客户端块。 “CRT 块”是由 CRT 库为自己使用而分配的内存块。CRT 库处理这些块的释放,因此您不大可能在内存泄漏报告中看到这些块,除非出现严重错误(例如 CRT 库损坏)。 从不会在内存泄漏信息中看到下面两种块类型:
“可用块”是已释放的内存块。 “忽略块”是您已特别标记的块,因而不出现在内存泄漏报告中。
-
十六进制形式的内存位置。 -
以字节为单位的块大小。 -
前 16 字节的内容(亦为十六进制)。
_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
2.2、定位具体的内存泄漏地方
|
_CrtMemState s1, s2, s3; |
|
_CrtMemCheckpoint( &s1 ); |
|
_CrtMemDumpStatistics( &s1 ); |
|
_CrtMemCheckpoint( &s1 ); // memory allocations take place here _CrtMemCheckpoint( &s2 ); if ( _CrtMemDifference( &s3, &s1, &s2) ) _CrtMemDumpStatistics( &s3 ); |
3、Linux平台下的内存泄漏检测
==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)
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 first line ("Heap Summary") tells you what kind of error it is.
• Below the first 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:
• "definitely lost": your program is leaking memory -- fix 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)
4、总结
-
程序员要养成良好习惯,保证malloc/new和free/delete匹配; -
检测内存泄漏的关键原理就是,检查malloc/new和free/delete是否匹配,一些工具也就是这个原理。要做到这点,就是利用宏或者钩子,在用户程序与运行库之间加了一层,用于记录内存分配情况。
出处:http://www.cnblogs.com/skynet/
原文始发于微信公众号(汇编语言):C/C++内存泄漏及检测
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论