ImageVerifierCode 换一换
格式:DOCX , 页数:12 ,大小:24.56KB ,
资源ID:4052469      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/4052469.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(内存泄露.docx)为本站会员(b****4)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

内存泄露.docx

1、内存泄露 1.msdn 在debug模式下的内存结构(曾今在gaia引擎里看过类似的自己模仿实现的内存管理结构)typedef struct _CrtMemBlockHeader/ Pointer to the block allocated just before this one: struct _CrtMemBlockHeader *pBlockHeaderNext; / Pointer to the block allocated just after this one: struct _CrtMemBlockHeader *pBlockHeaderPrev; char *szFile

2、Name; / File name int nLine; / Line number size_t nDataSize; / Size of user block int nBlockUse; / Type of block long lRequest; / Allocation number/ Buffer just before (lower than) the users memory: unsigned char gapnNoMansLandSize; _CrtMemBlockHeader;/* In an actual memory block in the debug heap,*

3、 this structure is followed by:* unsigned char datanDataSize;* unsigned char anotherGapnNoMansLandSize;/防止内存写越界*/The “NoMansLand” buffers on either side of the user data area of the block are currently 4 bytes in size, and are filled with a known byte value used by the debug heap routines to verify

4、that the limits of the users memory block have not been overwritten. The debug heap also fills new memory blocks with a known value. If you elect to keep freed blocks in the heaps linked list as explained below, these freed blocks are also filled with a known value. Currently, the actual byte values

5、 used are as follows: NoMansLand (0xFD) The “NoMansLand” buffers on either side of the memory used by an application are currently filled with 0xFD. Freed blocks (0xDD) The freed blocks kept unused in the debug heaps linked list when the _CRTDBG_DELAY_FREE_MEM_DF flag is set are currently filled wit

6、h 0xDD. New objects (0xCD) New objects are filled with 0xCD when they are allocated. 2._CrtDumpMemLeaks() msdn说明 The _CrtDumpMemoryLeaks function determines whether a memory leak has occurred since the start of program execution. When a leak is found, the debug header information for all of the obje

7、cts in the heap is dumped in a user-readable form. When _DEBUG is not defined, calls to _CrtDumpMemoryLeaks are removed during preprocessing. _CrtDumpMemoryLeaks is frequently called at the end of program execution to verify that all memory allocated by the application has been freed. The function c

8、an be called automatically at program termination by turning on the _CRTDBG_LEAK_CHECK_DF bit field of the _crtDbgFlag flag using the _CrtSetDbgFlag function. _CrtDumpMemoryLeaks calls _CrtMemCheckpoint to obtain the current state of the heap and then scans the state for blocks that have not been fr

9、eed. When an unfreed block is encountered, _CrtDumpMemoryLeaks calls _CrtMemDumpAllObjectsSince to dump information for all of the objects allocated in the heap from the start of program execution. By default, internal C run-time blocks (_CRT_BLOCK ) are not included in memory dump operations. The _

10、CrtSetDbgFlag function can be used to turn on the _CRTDBG_CHECK_CRT_DF bit of _crtDbgFlag to include these blocks in the leak detection process. For more information about heap state functions and the _CrtMemState structure, see the Heap State Reporting Functions . For information about how memory b

11、locks are allocated, initialized, and managed in the debug version of the base heap, see Memory Management and the Debug Heap . 应用: #include stdafx.h#include #ifdef _DEBUG#define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, _FILE_, _LINE_)#else#define DEBUG_CLIENTBLOCK#endif#define _CRTDBG_MAP_ALLOC#includ

12、e #ifdef _DEBUG#define new DEBUG_CLIENTBLOCK#endif /此部分用于使_CrtDumpMemoryLeaks输出内存泄漏文件名和行号信息默认不会输出相关信息void Exit int i = _CrtDumpMemoryLeaks; assert( i = 0);int _tmain(int argc, _TCHAR* argv) atexit(Exit); int* p = new int; return 0;不含红色部分输出:Detected memory leaks!Dumping objects -112 normal block at 0

13、x003AA770, 4 bytes long.Data: 00 00 00 00 Object dump complete.含红色部分输出:Detected memory leaks!Dumping objects -d:codeconsoletestconsoletest.cpp(21) : 112 client block at 0x003A38B0, subtype 0, 4 bytes long.Data: 00 00 00 00 Object dump complete.1._CrtDumpMemoryLeaks确定自程序开始执行以来是否发生过内存泄漏,如果发生过,则转储所有已分配

14、对象。如果已使用 _CrtSetDumpClient 安装了挂钩函数,那么,_CrtDumpMemoryLeaks每次转储 _CLIENT_BLOCK 块时,都会调用应用程序所提供的挂钩函数。 CrtDumpMemoryLeaks()就是显示当前的内存泄漏。 注意是“当前”,也就是说当它执行时,所有未销毁的对象均会报内存泄漏。因此尽量让这条语句在程序的最后执行。它所反映的是检测到泄漏的地方。一般用在MFC中比较准确,在InitInstance里面调用_CrtDumpMemoryLeaks2.信息输出Detected memory leaks!Dumping objects -52 normal

15、 block at 0x006D2498, 512 bytes long.?Data: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 51 normal block at 0x006D2440, 24 bytes long.?Data: 10 34 14 00 FF FF FF FF 00 00 00 00 00 00 00 00 Object dump complete.3._CrtSetBreakAlloc知道某个错误分配块的分配请求编号后,可以将该编号传递给 _CrtSetBreakAlloc 以创建一个断点_CrtSetBreakAll

16、oc(51);这样可以快速在51次内存泄漏处设上断点。/*/最快速度找到内存泄漏许式伟2006年11月某日内存管理是C+程序员的痛。我的内存管理变革 系列就是试图讨论更为有效的内存管理方式,以杜绝(或减少)内存泄漏,减轻C+程序员的负担。由于工作忙的缘故,这个系列目前未完,暂停。文我想换个方式,讨论一下如何以最快的速度找到内存泄漏。确认是否存在内存泄漏我们知道,MFC程序如果检测到存在内存泄漏,退出程序的时候会在调试窗口提醒内存泄漏。例如:class CMyApp : public CWinApppublic : BOOL InitApplication() int * leak = new

17、int 10 ; return TRUE; ; 产生的内存泄漏报告大体如下:Detected memory leaks ! Dumping objects - c:worktest.cpp( 186 ) : 52 normal block at 0x003C4410 , 40 bytes long .Data: CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD Object dump complete. 这挺好。问题是,如果我们不喜欢MFC,那么难道就没有办法?或者自己做? 呵呵,这不需要。其实,MFC也没有自己做。内存泄漏检测的工作是VC+的C运

18、行库做的。也就是说,只要你是VC+程序员,都可以很方便地检测内存泄漏。我们还是给个样例:#include inline void EnableMemLeakCheck() _CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);void main() EnableMemLeakCheck(); int * leak = new int 10 ; 运行(提醒:不要按Ctrl+F5,按F5),你将发现,产生的内存泄漏报告与MFC类似,但有细节不同,如下:Detected memory leaks ! D

19、umping objects - 52 normal block at 0x003C4410 , 40 bytes long .Data: CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD Object dump complete. 为什么呢?看下面。定位内存泄漏由于哪一句话引起的你已经发现程序存在内存泄漏。现在的问题是,我们要找泄漏的根源。一般我们首先确定内存泄漏是由于哪一句引起。在MFC中,这一点很容易。你双击内存泄漏报告的文字,或者在Debug窗口中按F4,IDE就帮你定位到申请该内存块的地方。对于上例,也就是这一句: int* leak =

20、 new int10;这多多少少对你分析内存泄漏有点帮助。特别地,如果这个new仅对应一条delete(或者你把delete漏写),这将很快可以确认问题的症结。 我们前面已经看到,不使用MFC的时候,生成的内存泄漏报告与MFC不同,而且你立刻发现按F4不灵。那么难道MFC做了什么手脚? 其实不是,我们来模拟下MFC做的事情。看下例: inline void EnableMemLeakCheck() _CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);#ifdef _DEBUG#define ne

21、w new(_NORMAL_BLOCK, _FILE_, _LINE_) #endif void main() EnableMemLeakCheck(); int * leak = new int 10 ;再运行这个样例,你惊喜地发现,现在内存泄漏报告和MFC没有任何分别了。快速找到内存泄漏单确定了内存泄漏发生在哪一行,有时候并不足够。特别是同一个new对应有多处释放的情形。在实际的工程中,以下两种情况很典型: 创建对象的地方是一个类工厂(ClassFactory)模式。很多甚至全部类实例由同一个new创建。对于此,定位到了new出对象的所在行基本没有多大帮助。 COM对象。我们知道COM对象

22、采用Reference Count维护生命周期。也就是说,对象new的地方只有一个,但是Release的地方很多,你要一个个排除。 那么,有什么好办法,可以迅速定位内存泄漏?答:有。在内存泄漏情况复杂的时候,你可以用以下方法定位内存泄漏。这是我个人认为通用的内存泄漏追踪方法中最有效的手段。我们再回头看看crtdbg生成的内存泄漏报告: Detected memory leaks ! Dumping objects - c:worktest.cpp( 186 ) : 52 normal block at 0x003C4410 , 40 bytes long .Data: CD CD CD CD

23、CD CD CD CD CD CD CD CD CD CD CD CD Object dump complete. 除了产生该内存泄漏的内存分配语句所在的文件名、行号为,我们注意到有一个比较陌生的信息:52。这个整数值代表了什么意思呢?其实,它代表了第几次内存分配操作。象这个例子,52代表了第52次内存分配操作发生了泄漏。你可能要说,我只new过一次,怎么会是第52次?这很容易理解,其他的内存申请操作在C的初始化过程调用的呗。:)有没有可能,我们让程序运行到第52次内存分配操作的时候,自动停下来,进入调试状态?所幸,crtdbg确实提供了这样的函数:即 long _CrtSetBreakAll

24、oc (long nAllocID)。我们加上它:inline void EnableMemLeakCheck() _CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);#ifdef _DEBUG#define new new(_NORMAL_BLOCK, _FILE_, _LINE_) #endif void main() EnableMemLeakCheck(); _CrtSetBreakAlloc ( 52 ); int * leak = new int 10 ; 你发现,程序运行到 int

25、 * leak = new int 10 ; 一句时,自动停下来进入调试状态。细细体会一下,你可以发现,这种方式你获得的信息远比在程序退出时获得文件名及行号有价值得多。因为报告泄漏文件名及行号,你获得的只是静态的信息,然而_CrtSetBreakAlloc 则是把整个现场恢复,你可以通过对函数调用栈分析(我发现很多人不习惯看函数调用栈,如果你属于这种情况,我强烈推荐你去补上这一课,因为它太重要了)以及其他在线调试技巧,来分析产生内存泄漏的原因。通常情况下,这种分析方法可以在5分钟内找到肇事者。 当然,_CrtSetBreakAlloc 要求你的程序执行过程是可还原的(多次执行过程的内存分配顺序

26、不会发生变化)。这个假设在多数情况下成立。不过,在多线程的情况下,这一点有时难以保证。 附加说明:对“内存管理”相关的技术感兴趣?这里可以看到我的所有关于内存管理的文章 。/*/ VC使用CRT调试功能来检测内存泄漏 作者:JerryZ C/C+ 编程语言的最强大功能之一便是其动态分配和释放内存,但是中国有句古话:“最大的长处也可能成为最大的弱点”,那么 C/C+ 应用程序正好印证了这句话。在 C/C+ 应用程序开发过程中,动态分配的内存处理不当是最常见的问题。其中,最难捉摸也最难检测的错误之一就是内存泄漏,即未能正确释放以前分配的内存的错误。偶尔发生的少量内存泄漏可能不会引起我们的注意,但泄

27、漏大量内存的程序或泄漏日益增多的程序可能会表现出各种各样的征兆:从性能不良(并且逐渐降低)到内存完全耗尽。更糟的是,泄漏的程序可能会用掉太多内存,导致另外一个程序垮掉,而使用户无从查找问题的真正根源。此外,即使无害的内存泄漏也可能殃及池鱼。幸运的是,Visual Studio 调试器和 C 运行时 (CRT) 库为我们提供了检测和识别内存泄漏的有效方法。下面请和我一起分享收获如何使用 CRT 调试功能来检测内存泄漏?一、如何启用内存泄漏检测机制VC+ IDE 的默认状态是没有启用内存泄漏检测机制的,也就是说即使某段代码有内存泄漏,调试会话的 Output 窗口的 Debug 页不会输出有关内存

28、泄漏信息。你必须设定两个最基本的机关来启用内存泄漏检测机制。一是使用调试堆函数:#define _CRTDBG_MAP_ALLOC #include #include注意:#include 语句的顺序。如果更改此顺序,所使用的函数可能无法正确工作。通过包含 crtdbg.h 头文件,可以将 malloc 和 free 函数映射到其“调试”版本 _malloc_dbg 和 _free_dbg,这些函数会跟踪内存分配和释放。此映射只在调试(Debug)版本(也就是要定义 _DEBUG)中有效。发行版本(Release)使用普通的 malloc 和 free 函数。#define 语句将 CRT 堆

29、函数的基础版本映射到对应的“调试”版本。该语句不是必须的,但如果没有该语句,那么有关内存泄漏的信息会不全。二是在需要检测内存泄漏的地方添加下面这条语句来输出内存泄漏信息:_CrtDumpMemoryLeaks();当在调试器下运行程序时,_CrtDumpMemoryLeaks 将在 Output 窗口的 Debug 页中显示内存泄漏信息。比如: Detected memory leaks!Dumping objects -C:Tempmemleakmemleak.cpp(15) : 45 normal block at 0x00441BA0, 2 bytes long.Data: 41 42c:program filesmicrosoft visual studiovc98includecrtdbg.h(552) :

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1