青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

春暖花開
雪化了,花開了,春天來了
posts - 149,comments - 125,trackbacks - 0
 

檢測內存泄露的工具:debugnew
http://dev.csdn.net/article/58/58407.shtm

網上有一個流傳甚廣的檢測內存泄露的工具:debugnew(debugnew.h/debugnew.cpp)
用法很簡單,把debugnew.cpp放在項目里一起編譯,需要檢測的文件把debugnew.h嵌在文件的最前面。

為方便使用,對源代碼做了一些小的改動。

下面是一些簡單的說明:

1、new 的重載
void* operator new (size_t size, const char* file, int line);        ⑴
void* operator new [] (size_t size, const char*  file, int line);      ⑵

在需要檢測的文件里,重定義new
#define new new(__FILE__, __LINE__)

造成的結果:
ClassName *p = new ClassName; => ClassName *p = new(__FILE__, __LINE__) ClassName;
// 實際會調用void* operator new (size_t size, const char* file, int line);

ClassName **pp = new classname[count]; => ClassName **pp = new(__FILE__, __LINE__) ClassName[count];
// 實際會調用void* operator new [] (size_t size, const char*  file, int line);

這其實是利用了placement new的語法,通過一個簡單的宏,就可以把普通的new操作對應到相應的重載( ⑴,⑵ )上去。

2、delete 的重載
void operator delete (void* p, const char* file, int line);                   ⑶
void operator delete [] (void* p, const char* file, int line);                ⑷
void operator delete (void* p);                                               ⑸
void operator delete [] (void* p);                                            ⑹

因為沒有類似于placement new的語法,所以就不能用一個宏來替換替換delete了。要調用帶有更多信息的delete操作符,只能修改源代碼了。
delete p; => delete ( p, __FILE__, __LINE__ );
delete []pp; => delete [] ( pp, __FILE__, __LINE__ );
但這個工作很煩瑣,如果并不需要多余的信息的話,簡單地重載delete( ⑸,⑹ )就可以了。

3、檢測和統計
程序開始時,在debugnew.cpp中會創建一個DebugNewTracer對象
在重載的new操作符( ⑴,⑵ )中,每一次內存分配都會被記錄,而在delete( ⑶,⑷,⑸,⑹ )中則會刪除相應的記錄。
當程序結束,DebugNewTracer對象被銷毀,它的析構函數會dump剩余的記錄,這就是泄露的內存了。

在原有代碼的基礎上,增加了記錄size的功能,這樣可以在每次new和delete時,看到實際占用的內存。所有信息可以dump出來,也可以寫入log。


5、源代碼

********************************************************
debugnew.h:

/*
 filename: debugnew.h
 
 This code is based on code retrieved from a web site. The
 author was not identified, so thanks go to anonymous.

 This is used to substitute a version of the new operator that
 can be used for debugging memory leaks. To use it:
 
 - In any (all?) code files #include debugnew.h. Make sure all
  system files (i.e. those in <>'s) are #included before
  debugnew.h, and that any header files for your own code
  are #included after debugnew.h. The reason is that some
  system files refer to ::new, and this will not compile
  if debugnew is in effect. You may still have problems
  if any of your own code refers to ::new, or if any
  of your own files #include system files that use ::new
  and which have not already been #included before
  debugnew.h.
 - Add debugnew.cpp to the CodeWarrior project or compile
  it into your Linux executable. If debugnew.cpp is in the
  project, then debugnew.h must be #included in at least
  one source file
*/

#ifndef __DEBUGNEW_H__
#define __DEBUGNEW_H__

#include <map>

#define LOG_FILE

#if defined(LOG_FILE)
#define LOG_FILE_NAME "./debugnew.log"
#endif

void* operator new (std::size_t size, const char* file, int line);
void operator delete (void* p, const char* name, int line);
void* operator new [] (std::size_t size, const char* file, int line);
void operator delete [] (void* p, const char* name, int line);

class DebugNewTracer  {
private:
 
 class Entry  {
 public:
  Entry (char const* file, int line) : _file (file), _line (line) {}
  Entry (char const* file, int line, int size) : _file (file), _line (line), _size (size) {}
  Entry () : _file (0), _line (0), _size (0) {}
  const char* File () const { return _file; }
  int Line () const { return _line; }
  size_t Size () const { return _size; }
 private:
  char const* _file;
  int _line;
  size_t _size;
 };

 class Lock {
 public:
  Lock (DebugNewTracer & DebugNewTracer) : _DebugNewTracer (DebugNewTracer) {
   _DebugNewTracer.lock ();
  }
  ~Lock () {
   _DebugNewTracer.unlock ();
  }
 private:
  DebugNewTracer & _DebugNewTracer;
 };
 typedef std::map<void*, Entry>::iterator iterator;
 friend class Lock;
 public:
 DebugNewTracer ();
 ~DebugNewTracer ();
 void Add (void* p, const char* file, int line);
 void Add (void* p, const char* file, int line, size_t size);
 void Remove (void* p);
 void Dump ();

 static bool Ready;

 private:
 void lock () { _lockCount++; }
 void unlock () { _lockCount--; }

 private:

 std::map<void*, Entry> _map;
 int _lockCount;
 size_t _totalsize;
#if defined(LOG_FILE)
 FILE* _logfp;
#endif
 };

 // The file that implements class DebugNewTracer
 // does NOT want the word "new" expanded.
 // The object DebugNewTrace is defined in that
 // implementation file but only declared in any other file.
#ifdef DEBUGNEW_CPP
DebugNewTracer DebugNewTrace;
#else
#define new new(__FILE__, __LINE__)
extern DebugNewTracer DebugNewTrace;
#endif

#endif//#ifndef __DEBUGNEW_H__


********************************************************
debugnew.cpp:

/*
 filename: debugnew.cpp

 This is used to substitute a version of the new operator that
 can be used for debugging memory leaks. In any (all?) code
 files #include debugnew.h. Add debugnew.cpp to the project.
*/

#include <iostream>
#include <map>

using namespace std;

 // This disables macro expansion of "new".
 // This statement should only appear in this file.
#define DEBUGNEW_CPP

#include "debugnew.h"

DebugNewTracer::DebugNewTracer () : _lockCount (0)
{
  // Once this object is constructed all calls to
  // new should be traced.

 Ready = true;
 _totalsize = 0;
#if defined(LOG_FILE)
 if( (_logfp=fopen(LOG_FILE_NAME,"wt")) == NULL )
 {
  printf(" Error! file: debugnew.log can not open@!\n");
  return;
 } 
 fprintf(_logfp,"new, delete list:\n");
 fflush(_logfp);
#endif
 
}
        
void DebugNewTracer::Add (void* p, const char* file, int line)
{
  // Tracing must not be done a second time
  // while it is already
  // in the middle of executing
 if (_lockCount > 0)
  return;

   // Tracing must be disabled while the map
   // is in use in case it calls new.
 DebugNewTracer::Lock lock (*this);
 _map [p] = Entry (file, line);
}

void DebugNewTracer::Add (void* p, const char* file, int line, size_t size)
{
 // Tracing must not be done a second time
 // while it is already
 // in the middle of executing
 if (_lockCount > 0)
  return;

  // Tracing must be disabled while the map
  // is in use in case it calls new.
 DebugNewTracer::Lock lock (*this);
#if 1
 //´Óȫ·¾¶ÖÐÌáÈ¡ÎļþÃû
 //linuxϵÄgcc,__FILE__½ö½ö°üÀ¨ÎļþÃû£¬windowsϵÄvc,__FILE__°üÀ¨È«Â·¾¶,ËùÒÔÓÐÕâÑùµÄ´¦Àí
 file = strrchr(file,'\\')== NULL?file:strrchr(file,'\\')+1;
#endif
 _map [p] = Entry (file, line, size);
 _totalsize += size;
#if defined(LOG_FILE)
 fprintf(_logfp,"*N p = 0x%08x, size = %6d,  %-22s, Line: %4d.  totalsize =%8d\n", p, size, file, line, _totalsize);
 fflush(_logfp);
#endif
}


void DebugNewTracer::Remove (void* p)
{
 // Tracing must not be done a second time
 // while it is already
 // in the middle of executing
 if (_lockCount > 0)
  return;

  // Tracing must be disabled while the map
  // is in use in case it calls new.
 DebugNewTracer::Lock lock (*this);

 iterator it = _map.find (p);

 if (it != _map.end ())
 {
  size_t size = (*it).second.Size();
  _totalsize -= size;
#if defined(LOG_FILE)
  fprintf(_logfp,"#D p = 0x%08x, size = %6u.%39stotalsize =%8d\n", p, size, "-----------------------------------  ", _totalsize );
  fflush(_logfp);
#endif
  _map.erase (it);
 }
 else
 {
#if defined(LOG_FILE)
  fprintf(_logfp,"#D p = 0x%08x. error point!!!\n", p );
  fflush(_logfp);
#endif
 }
}

DebugNewTracer::~DebugNewTracer ()
{
 // Trace must not be called if Dump indirectly
 // invokes new, so it must be disabled before
 // Dump is called. After this destructor executes
 // any other global objects that get destructed
 // should not do any tracing.
 Ready = false;
 Dump ();
#if defined(LOG_FILE)
 fclose(_logfp);
#endif
}

// If some global object is destructed after DebugNewTracer
// and if that object calls new, it should not trace that
// call to new.
void DebugNewTracer::Dump ()
{
 if (_map.size () != 0)
 {
  std::cout << _map.size () << " memory leaks detected\n";
#if defined(LOG_FILE)
  fprintf(_logfp, "\n\n***%d memory leaks detected\n", _map.size ());
  fflush(_logfp);
#endif
  for (iterator it = _map.begin (); it != _map.end (); ++it)
  {
   char const * file = it->second.File ();
   int line = it->second.Line ();
   int size = it->second.Size ();
   std::cout << file << ", "  << line << std::endl;
#if defined(LOG_FILE)
   fprintf(_logfp,"%s, %d, size=%d\n", file, line, size);
   fflush(_logfp);
#endif
  }
 }
 else
 {
  std::cout << "no leaks detected\n";
#if defined(LOG_FILE)
  fprintf(_logfp,"no leaks detected\n");
  fflush(_logfp);
#endif
 }

}

// If some global object is constructed before DebugNewTracer
// and if that object calls new, it should not trace that
// call to new.
bool DebugNewTracer::Ready = false;

void* operator new (size_t size, const char* file, int line)
{
 void * p = malloc (size);
 if (DebugNewTracer::Ready)
  DebugNewTrace.Add (p, file, line, size);
 return p;
}

void operator delete (void* p, const char* file, int line)
{
 file = 0; // avoid a warning about argument not used in function
 line = 0; // avoid a warning about argument not used in function
 
 if (DebugNewTracer::Ready)
  DebugNewTrace.Remove (p);
 free (p);
}
        
void* operator new [] (size_t size, const char*  file, int line)
{
 void * p = malloc (size);
 if (DebugNewTracer::Ready)
  DebugNewTrace.Add (p, file, line, size);
 return p;
}

void operator delete [] (void* p, const char* file, int line)
{
 file = 0; // avoid a warning about argument not used in function
 line = 0; // avoid a warning about argument not used in function
 
 if (DebugNewTracer::Ready)
   DebugNewTrace.Remove (p);
 free (p);
}
        
void* operator new (size_t size)
{
 void * p = malloc (size);
 // When uncommented these lines cause entries in the map for calls to new
 // that were not altered to the debugnew version. These are likely calls
 // in library functions and the presence in the dump of these entries
 // is usually misleading.
 // if (DebugNewTracer::Ready)
 //   DebugNewTrace.Add (p, "?", 0);
 return p;
}
 
void operator delete (void* p)
{
 if (DebugNewTracer::Ready)
  DebugNewTrace.Remove (p);
 free (p);
}

//add by yugang
void operator delete [] (void* p)
{
 if (DebugNewTracer::Ready)
  DebugNewTrace.Remove (p);
 free (p);
}

posted on 2008-11-02 10:52 Sandy 閱讀(760) 評論(0)  編輯 收藏 引用 所屬分類: C++
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲国产精品成人久久综合一区| 亚洲国产高清高潮精品美女| 国产亚洲成人一区| 禁断一区二区三区在线 | 99国产精品久久久久久久| 午夜精品福利视频| 欧美高清视频免费观看| 国产午夜精品全部视频在线播放| 午夜精品久久久久久99热| 欧美va天堂在线| 亚洲免费一级电影| 欧美高清视频一区| 一区二区久久| 欧美国产一区视频在线观看| 亚洲欧美日韩在线一区| 国产精品永久免费在线| 亚洲人成精品久久久久| 久久婷婷影院| 亚洲欧美日韩国产综合在线 | 欧美jizzhd精品欧美喷水 | 欧美影院精品一区| 国产精品成人在线| 亚洲精品三级| 另类图片国产| 欧美影院成年免费版| 亚洲国产高清视频| 亚洲精品免费一二三区| 免费91麻豆精品国产自产在线观看| 国产精品一区二区三区四区五区| 久久精品视频va| 午夜精品久久久久久久99水蜜桃 | 日韩午夜高潮| 亚洲国产日韩欧美综合久久| 久久婷婷色综合| 国内精品视频在线播放| 久久久久久香蕉网| 久久精品天堂| 1024亚洲| 亚洲高清视频在线观看| 国产精品日韩欧美| 久久精品视频一| 欧美激情视频一区二区三区免费 | 欧美视频在线观看| 亚洲一区二区三区精品视频| 日韩亚洲欧美一区二区三区| 欧美日韩亚洲成人| 亚洲欧美成aⅴ人在线观看| 中日韩高清电影网| 国产区精品在线观看| 久久久久久久久久久成人| 欧美一区二区在线免费观看| 欧美成人中文字幕| 91久久久亚洲精品| 亚洲一区二区三区777| 欧美午夜一区二区| 亚洲桃色在线一区| 在线视频免费在线观看一区二区| 国产亚洲欧美另类一区二区三区| 欧美在线视频在线播放完整版免费观看| 欧美黑人一区二区三区| 国产日韩视频| 一区二区欧美激情| 国产精品免费看片| 久久精品欧洲| 国产精品v亚洲精品v日韩精品| 麻豆国产精品一区二区三区| 欧美阿v一级看视频| 欧美自拍偷拍午夜视频| 欧美日韩精品在线视频| 亚洲福利视频三区| 欧美在线视频在线播放完整版免费观看| 亚洲高清影视| 久久国产精品一区二区| 欧美三级在线播放| 亚洲激情视频在线| 国产精品第一区| 亚洲高清精品中出| 在线日韩中文| 亚洲一二三区在线| 国语精品中文字幕| 亚洲欧美日韩一区在线| 亚洲一区二区高清| 欧美日韩一级大片网址| 欧美成人嫩草网站| 亚洲尤物精选| 欧美亚洲综合在线| 国产精品久在线观看| 日韩视频永久免费观看| 日韩午夜电影av| 欧美精品成人91久久久久久久| 免费观看在线综合| 尤物在线观看一区| 亚洲国产欧美日韩| 亚洲视频在线视频| 亚洲一区中文字幕在线观看| 久久精品视频99| 久久露脸国产精品| 国产精品视频1区| 亚洲永久免费观看| 久久久久国产精品www| 亚洲国产精品一区在线观看不卡| 久久一区二区三区四区| 亚洲第一黄色| 亚洲天堂av电影| 欧美午夜片欧美片在线观看| 一区二区三区四区五区视频| 亚洲综合精品四区| 国产一级揄自揄精品视频| 日韩视频免费观看高清在线视频 | 欧美国产在线观看| 日韩小视频在线观看| 亚洲欧美电影院| 国产欧美精品| 久久亚洲欧美国产精品乐播| 亚洲激情二区| 午夜欧美不卡精品aaaaa| 国产精品久久久久久久久果冻传媒 | 欧美国产免费| 亚洲特黄一级片| 欧美不卡高清| 亚洲欧美日韩国产一区二区三区 | 亚洲精品免费网站| 久久aⅴ国产紧身牛仔裤| …久久精品99久久香蕉国产| 欧美三级电影网| 久久精品国语| 99精品视频免费观看| 久久免费偷拍视频| 亚洲制服丝袜在线| 亚洲电影下载| 欧美日韩亚洲91| 久久嫩草精品久久久精品一| 一区二区三区 在线观看视| 久久免费视频网| 在线亚洲+欧美+日本专区| 黄色亚洲精品| 国产精品久久福利| 久久精品国产99精品国产亚洲性色| 欧美激情按摩在线| 香蕉av福利精品导航| 99精品热6080yy久久| 好吊妞这里只有精品| 国产精品成人观看视频免费| 欧美.www| 美国三级日本三级久久99| 亚洲一区在线看| 久久亚洲春色中文字幕| 欧美在线观看网址综合| 亚洲欧美在线观看| 夜夜嗨av一区二区三区四季av | 久久综合一区二区| 欧美一区永久视频免费观看| 亚洲免费av网站| 91久久中文字幕| 在线免费日韩片| 国产精品日本精品| 欧美日韩一级视频| 欧美日韩免费在线视频| 免费欧美在线| 欧美成人国产va精品日本一级| 久久精品亚洲乱码伦伦中文| 欧美一区二区在线免费观看| 亚洲已满18点击进入久久| 免费看黄裸体一级大秀欧美| 你懂的视频欧美| 欧美成人免费全部观看天天性色| 美女主播一区| 欧美成人在线网站| 欧美激情日韩| 欧美成黄导航| 亚洲欧洲在线一区| 乱人伦精品视频在线观看| 久久伊人精品天天| 欧美成人综合网站| 最新中文字幕亚洲| 亚洲免费电影在线观看| 日韩一级免费| 亚洲一级片在线看| 欧美一区三区三区高中清蜜桃| 久久av最新网址| 久久亚洲捆绑美女| 欧美精品在线观看| 99视频国产精品免费观看| 一区二区三区欧美成人| 欧美一级大片在线免费观看| 久久久久免费观看| 欧美成人国产一区二区 | 亚洲免费观看在线观看| 99精品国产在热久久下载| 亚洲午夜久久久| 亚洲精品日产精品乱码不卡| 欧美一区二区三区四区在线观看| 久久看片网站| 国产精品白丝黑袜喷水久久久 | 99精品欧美一区| 亚洲欧美卡通另类91av | 亚洲欧美一区二区三区久久| 久久久噜噜噜久久| 亚洲精品在线观看免费| 亚洲欧美国产视频|