内存泄露检测

    内存泄露是许多大规模程序中亟待解决的问题,下面是一点资料整理,帮我记忆吧。有VC自带的工具,也有免费的比较成熟的工具。控制台程序编译即可看到效果。

// = MemoryLeakDetect.cpp
/// 去掉注释观察VS2005自带内存检测工具效果
// #define DEFAULT_CRGDBG_MEM_CHECK
#ifndef DEFAULT_CRGDBG_MEM_CHECK
    
//  = vld内存泄露检测
     ///   http://www.codeproject.com/tools/visualleakdetector.asp
    
///  Visual Leak Detector - Enhanced Memory Leak Detection for Visual C++
    #include  < vld.h >
#else
    
//  = VS2005自带内存检测设施
     ///   http://www.vckbase.com/document/viewdoc/?id=1349
    
///  VC++ 6.0 中如何使用 CRT 调试功能来检测内存泄漏
     #define  _CRTDBG_MAP_ALLOC
    #include 
< stdlib.h >
    #include 
< crtdbg.h >
    
///  确定准确的内存泄露位置
    #include  " debug_new.h "
#endif

//  = UNICODE or ANSI
#include  < tchar.h >
#include 
< strsafe.h >

void  MemoryLeakDetectDemo()
{   
    
const  _TCHAR str[]  =  _T( " Hello the world!  Hello the children! " );
    _TCHAR 
* =   new  _TCHAR[ 128 ];    
    size_t size 
=   0 ;

    StringCchLength(str, 
1024 & size);
    StringCchCopy(p, size, str);
}

int  _tmain( int  argc, _TCHAR *  argv[])
{
#ifdef DEFAULT_CRGDBG_MEM_CHECK
    ///  程序无论从何种路径退出都会自动调用_CrtDumpMemoryLeaks
    ///_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF 
|  _CRTDBG_LEAK_CHECK_DF );
#endif

    MemoryLeakDetectDemo();

#ifdef DEFAULT_CRGDBG_MEM_CHECK
    _CrtDumpMemoryLeaks();
#endif

    
return   0 ;
}

 

//  = debug_new.h

#ifndef _DEBUG_NEW_H_
#define  _DEBUG_NEW_H_

#ifdef _DEBUG

#undef  new
extern   void  _RegDebugNew(  void  );
extern   void *  __cdecl  operator   new ( size_t,  const   char * int  );
extern   void  __cdecl  operator  delete(  void * const   char * int );
#define  new new(__FILE__, __LINE__)

#define  REG_DEBUG_NEW _RegDebugNew();

#else

#define  REG_DEBUG_NEW

#endif   //  _DEBUG

#endif   //  _DEBUG_NEW_H_

 

/* ********************************************************************** */
/*  comment:  此文件与debug_new.h配合使用,用于在调试期发现内存泄漏        */
/*            仅在VC++编译器中适用(包括Intel C++,因为它使用了相同的库)    */
/*  作者:     周星星  http://blog.vckbase.com/bruceteen/                    */
/*  版权申明: 无,可任意 使用,修改 和 发布                                 */
/* ********************************************************************** */

// #include "debug_new.h"

#ifdef _DEBUG

#include 
< windows.h >
#include 
< crtdbg.h >

class  _CriSec
{
    CRITICAL_SECTION criSection;
public :
    _CriSec()    { InitializeCriticalSection( 
& criSection ); }
    
~ _CriSec()   { DeleteCriticalSection(  & criSection );     }
    
void  Enter() { EnterCriticalSection(  & criSection );      }
    
void  Leave() { LeaveCriticalSection(  & criSection );      }
} _cs;

void  _RegDebugNew(  void  )
{
    _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG 
|  _CRTDBG_LEAK_CHECK_DF );
}
void *  __cdecl  operator   new ( size_t nSize,  const   char *  lpszFileName,  int  nLine )
{
    
//  comment 1: MFC中提供的debug new虽然加了锁,但我在实际测试的时候发现多线程并发
    
//             调用的时候还是抛出了系统错误,所以我在这里加了一个线程互斥量.
    
//  comment 2: debug new和debug delete之间需不需要互斥我并不知道,保险起见,我同样
    
//             加了线程互斥量.
    
//  comment 3: 按照C++标准规定,在operator new失败后应当调用set_new_handler设置的
    
//             函数,但是MSDN中却说"头文件new中的set_new_handler是stub的,而应该使
    
//             用头文件new.h中的_set_new_handler",这简直是滑天下之大稽.
    
//             以下是VC++6.0中的set_new_handler定义:
    
//                 new_handler __cdecl set_new_handler( new_handler new_p )
    
//                 {
    
//                     assert( new_p == 0 );  //  cannot use stub to register a new handler
    
//                     _set_new_handler( 0 );
    
//                     return 0;
    
//                 }
    
//             所以我也无计可施,只能舍弃set_new_handler的作用.

    _cs.Enter();
    
void *  p  =  _malloc_dbg( nSize, _NORMAL_BLOCK, lpszFileName, nLine );
    _cs.Leave();
    
return  p;
}
void  __cdecl  operator  delete(  void *  p,  const   char *   /* lpszFileName */ int   /* nLine */  )
{
    _cs.Enter();
    _free_dbg( p, _CLIENT_BLOCK );
    _cs.Leave();
}

#endif

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值