请尊重原作者的工作,转载时请务必注明转载自:www.xionggf.com
第2章 DxFramework的架构剖析 2 2.3 DxFramework的内存泄漏检测机制 内存泄漏(memory leak)是使用C/C++等程序设计语言进行编程时常常见到的一个问题。内存泄漏给程序运行时带来的影响有很多。一般最后的结果要么是程序死掉;要么是提示系统内存不足。还有一种可能就是程序不会死掉,但是程序的响应速度会明显变慢。
2.3.1 内存泄漏的原因 产生内存泄漏的原因一般是如下几点:
动态分配了内存空间,在不需要时忘记释放。 动态分配了内存空间,在不需要时忘记释放。 对某些API函数的不正确使用,导致内存泄漏。 在编程时忘记释放不需要的内存空间是编程时很常见。动态分配的内存在使用完毕后,如若不需要了就一定要释放。如果不释放,那就会造成内存的泄漏。如果造成内存泄漏的代码经常被调用的话,那么内存泄漏的数目就会越来越多的。从而影响整个系统的运行。 如下面的代码段:
void SomeOperation() { int* pBuffer = new int[32]; for( int i=0; i<32 ; ++i) { pBuffer[i] = i*2+1; } } 很明显,上述的局部变量pTemp指向了一段从堆(heap)空间中分配的内存空间,而在函数退出时没有作任何的释放操作。一旦调用此函数就将导致了内存泄漏。当这个函数被频繁调用的时候,堆空间的内存空间将会被消耗殆尽。
因为代码编写的问题,会导致某些动态分配的内存根本就无从回收,比如下面的代码段:
void SomeOperation() { int* pBuffer1 = new int[32]; int* pBuffer2 = new int[32]; pBuffer1 = pBuffer2; if( pBuffer1 ) { delete [] pBuffer1; } } 这样,pBuffer1最初指向的那段内存空间的首地址就丢掉了,无法恢复了。这时候最初分配的那一段内存空间就无法释放掉。
Windows提供了一些特殊的API,如FormatMessage。如果给它参数传递的函数有FORMAT_MESSAGE_ALLOCATE_BUFFER,它会在函数内部动态分配一块内存缓冲区,返回给用户。但是这个内存缓冲区需要用户显式调用LocalFree来释放。如果用户忘了的话。也会产生内存泄漏。如下面的代码段:
#include <windows.h> #include <iostream> using namespace std; void FormatAndPrintOneMessage(DWORD dwError) { HLOCAL hLocal = NULL; // 用来存储返回的描述错误信息的字符串的内存缓冲区 BOOL fOK = FormatMessage( // 指定标志,动态分配一块缓冲区 FORMAT_MESSAGE_FROM_SYSTEM |FORMAT_MESSAGE_ALLOCATE_BUFFER , NULL , dwError , MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US), // 返回动态分配的内存缓冲区 reinterpret_cast<LPTSTR>(&hLocal), 0 , NULL ); if( hLocal && fOK ) { cout<<"Error Message: "<<(reinterpret_cast<LPCTSTR> (LocalLock(hLocal)))<<endl; // 如果忘记了这一句,将会导致通过FormatMessage函数动态分配的 // 内存无法释放,从而导致内存泄漏 LocalFree(hLocal); } else { cout<<"Error number not found"<<endl; } } void main() { FormatAndPrintOneMessage(5); } 检查已经发布的程序是否存在内存泄漏实在是费时费力,所以我们要把内存泄漏扼杀在萌芽状态。在编码过程中就要时刻进行检查。