c++newオペレータをリロードし、メモリの漏洩を防止

13399 ワード

c++開発の過程で、メモリ漏洩はプログラマーを最も悩ませることであり、メモリ漏洩の場所を見つけるために長い間デバッグすることがある.newオペレータを再ロードすることは、多くの大規模なプロジェクトでよく使われるメモリ漏洩防止の手段です.私は暇で、newオペレータのリロード関数を書いて、みんなはお互いに勉強して、足りないところがあって、みんなに指摘してもらいたいです.
コードをつけると、あまり説明しません.
  1 #ifndef _BASE_H_
  2 #define _BASE_H_
  3 
  4 #include 
  5 #include 
  6 #include 
  7 using namespace std;
  8 
  9 typedef struct {
 10     unsigned long address;
 11     unsigned long size;
 12     char file[64];
 13     unsigned long line;
 14 } ALLOC_INFO;
 15 
 16 typedef maplong, ALLOC_INFO*> AllocMap;
 17 
 18 AllocMap* allocMap;
 19 
 20 #ifdef _DEBUG
 21 #define DEBUG_NEW new(__FILE__, __LINE__)
 22 
 23 void AddTrack(unsigned long addr, unsigned long asize, const char *fname, unsigned long lnum) 
 24 { 
 25     ALLOC_INFO *info = new ALLOC_INFO();
 26     info->address = addr;
 27     strncpy(info->file, fname, 63);
 28     info->line = lnum;
 29     info->size = asize;
 30     if (!allocMap)
 31     {
 32         allocMap = new AllocMap;
 33     }
 34     allocMap->insert(make_pair(addr,info));
 35 }
 36 
 37 void RemoveTrack(unsigned long addr)
 38 {
 39     if(!allocMap || 0 == allocMap->size())
 40     {
 41         return;
 42     }
 43     AllocMap::iterator iter = allocMap->find(addr);
 44     if (iter != allocMap->end())
 45     {
 46         ALLOC_INFO* info = iter->second;
 47         delete info;
 48         allocMap->erase(iter);
 49     }
 50 }
 51 
 52 inline void * operator new(unsigned int size, const char *file, int line)
 53 {
 54     void *ptr = (void *)malloc(size);
 55     AddTrack((unsigned long)ptr, size, file, line);
 56     return(ptr);
 57 }
 58 
 59 inline void operator delete(void *p)
 60 {
 61     RemoveTrack((unsigned long)p);
 62     free(p);
 63 }
 64 
 65 inline void * operator new[](unsigned int size, const char *file, int line)
 66 {
 67     void *ptr = (void *)malloc(size);
 68     AddTrack((unsigned long)ptr, size, file, line);
 69     return(ptr);
 70 }
 71 
 72 inline void operator delete[](void *p)
 73 {
 74     RemoveTrack((unsigned long)p);
 75     free(p);
 76 }
 77 #else  // _DEBUG
 78 #define DEBUG_NEW new
 79 #endif // _DEBUG
 80 
 81 //                
 82 void DumpUnfreed()
 83 {
 84     AllocMap::iterator iter;
 85     ALLOC_INFO* info;
 86     unsigned long totalSize = 0;
 87     if(!allocMap || 0 == allocMap->size())
 88     {
 89         return;
 90     }
 91 
 92     for(iter = allocMap->begin(); iter != allocMap->end(); iter++)
 93     {
 94         printf("%-50s: LINE %d, ADDRESS %d %d unfreed
", iter->second->file, iter->second->line 95 , iter->second->address, iter->second->size); 96 totalSize += iter->second->size; 97 info = iter->second; 98 delete info; 99 } 100 printf("-----------------------------------------------------------
"); 101 printf("Total Unfreed: %d bytes
", totalSize); 102 delete allocMap; 103 }; 104 105 #endif // _BASE_H_
1 #include "base.h"
2 #define new DEBUG_NEW
3 
4 int main()
5 {
6     char* pszCeshi = new char[5];
7     DumpUnfreed();
8     return 0;
9 }

最終的な実行結果は次のとおりです.
c:\c++\test\test\main.cpp                         : LINE 6, ADDRESS 6637816 5 unfreed ----------------------------------------------------------- Total Unfreed: 5 bytes
一部のコンパイラでは、warning C 4291:「void*operator new(unsigned int,const char*,int)」:一致する削除演算子が見つかりません.初期化によって例外が発生した場合、メモリは解放されません.
このエラーを防止するには、2つのdeleteメソッドを定義します.次のようになります.
inline void operator delete(void *p , const char *file, int line)
{
    RemoveTrack((unsigned long)p);
    free(p);
}

inline void operator delete[](void *p, const char *file, int line)
{
    RemoveTrack((unsigned long)p);
    free(p);
}