原因:
好处:
C++标准规定:
备注:
实现:
简单实现
1 void* operator new(size_t size) 2 { 3 if (size < 0) 4 return 0; 5 if (size == 0) 6 size = 1; 7 8 void *res = malloc(size); 9 return res; 10 } 11 12 void operator delete(void* p) 13 { 14 if (p != 0) 15 free(p); 16 } 17 18 void* operator new[](size_t size) 19 { 20 return operator new(size); 21 } 22 23 void operator delete[](void* src) 24 { 25 operator delete(src); 26 }
跨平台实现及其内存检测:(来源:http://www.linuxidc.com/Linux/2011-07/39154p4.htm)
1 #ifndef _DEBUG_NEW_H 2 #define _DEBUG_NEW_H 3 4 #include <new> 5 6 /* Prototypes */ 7 bool check_leaks(); 8 void* operator new(size_t size, const char* file, int line); 9 void* operator new[](size_t size, const char* file, int line); 10 #ifndef NO_PLACEMENT_DELETE 11 void operator delete(void* pointer, const char* file, int line); 12 void operator delete[](void* pointer, const char* file, int line); 13 #endif // NO_PLACEMENT_DELETE 14 void operator delete[](void*); // MSVC 6 requires this declaration 15 16 /* Macros */ 17 #ifndef DEBUG_NEW_NO_NEW_REDEFINITION 18 #define new DEBUG_NEW 19 #define DEBUG_NEW new(__FILE__, __LINE__) 20 #define debug_new new 21 #else 22 #define debug_new new(__FILE__, __LINE__) 23 #endif // DEBUG_NEW_NO_NEW_REDEFINITION 24 #ifdef DEBUG_NEW_EMULATE_MALLOC 25 #include <stdlib.h> 26 #define malloc(s) ((void*)(debug_new char[s])) 27 #define free(p) delete[] (char*)(p) 28 #endif // DEBUG_NEW_EMULATE_MALLOC 29 30 /* Control flags */ 31 extern bool new_verbose_flag; // default to false: no verbose information 32 extern bool new_autocheck_flag; // default to true: call check_leaks() on exit 33 34 #endif // _DEBUG_NEW_H 35 36 37 /* 38 * debug_new.cpp 1.11 2003/07/03 39 * 40 * Implementation of debug versions of new and delete to check leakage 41 * 42 * By Wu Yongwei 43 * 44 */ 45 46 #include <new> 47 #include <stdio.h> 48 #include <stdlib.h> 49 50 #ifdef _MSC_VER 51 #pragma warning(disable: 4073) 52 #pragma init_seg(lib) 53 #endif 54 55 #ifndef DEBUG_NEW_HASHTABLESIZE 56 #define DEBUG_NEW_HASHTABLESIZE 16384 57 #endif 58 59 #ifndef DEBUG_NEW_HASH 60 #define DEBUG_NEW_HASH(p) (((unsigned)(p) >> 8) % DEBUG_NEW_HASHTABLESIZE) 61 #endif 62 63 // The default behaviour now is to copy the file name, because we found 64 // that the exit leakage check cannot access the address of the file 65 // name sometimes (in our case, a core dump will occur when trying to 66 // access the file name in a shared library after a SIGINT). 67 #ifndef DEBUG_NEW_FILENAME_LEN 68 #define DEBUG_NEW_FILENAME_LEN 20 69 #endif 70 #if DEBUG_NEW_FILENAME_LEN == 0 && !defined(DEBUG_NEW_NO_FILENAME_COPY) 71 #define DEBUG_NEW_NO_FILENAME_COPY 72 #endif 73 #ifndef DEBUG_NEW_NO_FILENAME_COPY 74 #include <string.h> 75 #endif 76 77 struct new_ptr_list_t 78 { 79 new_ptr_list_t* next; 80 #ifdef DEBUG_NEW_NO_FILENAME_COPY 81 const char* file; 82 #else 83 char file[DEBUG_NEW_FILENAME_LEN]; 84 #endif 85 int line; 86 size_t size; 87 }; 88 89 static new_ptr_list_t* new_ptr_list[DEBUG_NEW_HASHTABLESIZE]; 90 91 bool new_verbose_flag = false; 92 bool new_autocheck_flag = true; 93 94 bool check_leaks() 95 { 96 bool fLeaked = false; 97 for (int i = 0; i < DEBUG_NEW_HASHTABLESIZE; ++i) 98 { 99 new_ptr_list_t* ptr = new_ptr_list[i]; 100 if (ptr == NULL) 101 continue; 102 fLeaked = true; 103 while (ptr) 104 { 105 printf("Leaked object at %p (size %u, %s:%d)/n", 106 (char*)ptr + sizeof(new_ptr_list_t), 107 ptr->size, 108 ptr->file, 109 ptr->line); 110 ptr = ptr->next; 111 } 112 } 113 if (fLeaked) 114 return true; 115 else 116 return false; 117 } 118 119 void* operator new(size_t size, const char* file, int line) 120 { 121 size_t s = size + sizeof(new_ptr_list_t); 122 new_ptr_list_t* ptr = (new_ptr_list_t*)malloc(s); 123 if (ptr == NULL) 124 { 125 fprintf(stderr, "new: out of memory when allocating %u bytes/n", 126 size); 127 abort(); 128 } 129 void* pointer = (char*)ptr + sizeof(new_ptr_list_t); 130 size_t hash_index = DEBUG_NEW_HASH(pointer); 131 ptr->next = new_ptr_list[hash_index]; 132 #ifdef DEBUG_NEW_NO_FILENAME_COPY 133 ptr->file = file; 134 #else 135 strncpy(ptr->file, file, DEBUG_NEW_FILENAME_LEN - 1); 136 ptr->file[DEBUG_NEW_FILENAME_LEN - 1] = '/0'; 137 #endif 138 ptr->line = line; 139 ptr->size = size; 140 new_ptr_list[hash_index] = ptr; 141 if (new_verbose_flag) 142 printf("new: allocated %p (size %u, %s:%d)/n", 143 pointer, size, file, line); 144 return pointer; 145 } 146 147 void* operator new[](size_t size, const char* file, int line) 148 { 149 return operator new(size, file, line); 150 } 151 152 void* operator new(size_t size) 153 { 154 return operator new(size, "<Unknown>", 0); 155 } 156 157 void* operator new[](size_t size) 158 { 159 return operator new(size); 160 } 161 162 void* operator new(size_t size, const std::nothrow_t&) throw() 163 { 164 return operator new(size); 165 } 166 167 void* operator new[](size_t size, const std::nothrow_t&) throw() 168 { 169 return operator new[](size); 170 } 171 172 void operator delete(void* pointer) 173 { 174 if (pointer == NULL) 175 return; 176 size_t hash_index = DEBUG_NEW_HASH(pointer); 177 new_ptr_list_t* ptr = new_ptr_list[hash_index]; 178 new_ptr_list_t* ptr_last = NULL; 179 while (ptr) 180 { 181 if ((char*)ptr + sizeof(new_ptr_list_t) == pointer) 182 { 183 if (new_verbose_flag) 184 printf("delete: freeing %p (size %u)/n", pointer, ptr->size); 185 if (ptr_last == NULL) 186 new_ptr_list[hash_index] = ptr->next; 187 else 188 ptr_last->next = ptr->next; 189 free(ptr); 190 return; 191 } 192 ptr_last = ptr; 193 ptr = ptr->next; 194 } 195 fprintf(stderr, "delete: invalid pointer %p/n", pointer); 196 abort(); 197 } 198 199 void operator delete[](void* pointer) 200 { 201 operator delete(pointer); 202 } 203 204 // Some older compilers like Borland C++ Compiler 5.5.1 and Digital Mars 205 // Compiler 8.29 do not support placement delete operators. 206 // NO_PLACEMENT_DELETE needs to be defined when using such compilers. 207 // Also note that in that case memory leakage will occur if an exception 208 // is thrown in the initialization (constructor) of a dynamically 209 // created object. 210 #ifndef NO_PLACEMENT_DELETE 211 void operator delete(void* pointer, const char* file, int line) 212 { 213 if (new_verbose_flag) 214 printf("info: exception thrown on initializing object at %p (%s:%d)/n", 215 pointer, file, line); 216 operator delete(pointer); 217 } 218 219 void operator delete[](void* pointer, const char* file, int line) 220 { 221 operator delete(pointer, file, line); 222 } 223 224 void operator delete(void* pointer, const std::nothrow_t&) 225 { 226 operator delete(pointer, "<Unknown>", 0); 227 } 228 229 void operator delete[](void* pointer, const std::nothrow_t&) 230 { 231 operator delete(pointer, std::nothrow); 232 } 233 #endif // NO_PLACEMENT_DELETE 234 235 // Proxy class to automatically call check_leaks if new_autocheck_flag is set 236 class new_check_t 237 { 238 public: 239 new_check_t() {} 240 ~new_check_t() 241 { 242 if (new_autocheck_flag) 243 { 244 // Check for leakage. 245 // If any leaks are found, set new_verbose_flag so that any 246 // delete operations in the destruction of global/static 247 // objects will display information to compensate for 248 // possible false leakage reports. 249 if (check_leaks()) 250 new_verbose_flag = true; 251 } 252 } 253 }; 254 static new_check_t new_check_object;
内存跟踪检测:boost库(来源:http://blog.csdn.net/zmyer/article/details/21475101)
1 #include<stdio.h> 2 #include<map> 3 #include<boost/thread/mutex.hpp> 4 #include<boost/thread/locks.hpp> 5 using namespace boost; 6 7 #define MEM_CHECK_TABLESIZE 1024*1024 8 #define MEM_HASH_FUNC(ptr) ((reinterpret_cast<unsigned long>(ptr))%MEM_CHECK_TABLESIZE) 9 #define MEM_FILENAME_SIZE 1024 10 11 boost::mutex mut; 12 boost::mutex mem_mut; 13 struct allocMem_ptr_t 14 { 15 allocMem_ptr_t() 16 { 17 bzero(fileName,sizeof(fileName)); 18 size = 0; 19 line = 0; 20 next = NULL; 21 } 22 char fileName[MEM_FILENAME_SIZE]; 23 int size; 24 int line; 25 allocMem_ptr_t* next; 26 }; 27 28 struct allocMem_ptr_t* allocMem_list[MEM_CHECK_TABLESIZE]; 29 int tableSize = 0; 30 31 struct memLeak_ptr_t 32 { 33 memLeak_ptr_t() 34 { 35 bzero(fileName,sizeof(fileName)); 36 size = 0; 37 } 38 char fileName[MEM_FILENAME_SIZE]; 39 int size; 40 }; 41 std::map<int,memLeak_ptr_t> memLeak_map; 42 void memCheck() 43 { 44 size_t index = 0; 45 mem_mut.lock(); 46 for(int i=0;i<MEM_CHECK_TABLESIZE;i++) 47 { 48 allocMem_ptr_t* alloc = allocMem_list[i]; 49 if(NULL == alloc) continue; 50 while(alloc) 51 { 52 memLeak_ptr_t memLeak; 53 sprintf(memLeak.fileName,"%s:%d",alloc->fileName,alloc->line); 54 memLeak.size = alloc->size; 55 memLeak_map.insert(std::make_pair(index,memLeak)); 56 alloc = alloc->next; 57 index++; 58 } 59 } 60 mem_mut.unlock(); 61 std::map<std::string,int> leakCount; 62 for(int i =0;i<memLeak_map.size();i++) 63 leakCount[memLeak_map[i].fileName] += memLeak_map[i].size; 64 typedef std::map<std::string,int>::iterator leakCount_iter; 65 for(leakCount_iter iter = leakCount.begin();iter != leakCount.end();++iter) 66 { 67 printf("%s LEAK MEMORY SIZE:%d\n",iter->first.c_str(),iter->second); 68 } 69 } 70 void* operator new(size_t size,const char* file,int line) 71 { 72 size_t siz = size + sizeof(allocMem_ptr_t); 73 allocMem_ptr_t* ptr = (allocMem_ptr_t*)::malloc(siz); 74 if(NULL == ptr) abort(); 75 void* p = (char*)ptr + sizeof(allocMem_ptr_t); 76 strncpy(ptr->fileName,file,MEM_FILENAME_SIZE-1); 77 ptr->size = size; 78 ptr->line = line; 79 80 mem_mut.lock(); 81 size_t index = MEM_HASH_FUNC(p); 82 ptr->next = allocMem_list[index]; 83 allocMem_list[index] = ptr; 84 ++tableSize; 85 mem_mut.unlock(); 86 return p; 87 } 88 89 void* operator new[](size_t size,const char* file,int line) 90 { 91 return operator new(size,file,line); 92 } 93 94 void operator delete(void* ptr) 95 { 96 if(NULL == ptr) return; 97 allocMem_ptr_t* pre = NULL; 98 size_t index = MEM_HASH_FUNC(ptr); 99 mem_mut.lock(); 100 allocMem_ptr_t* pointer = allocMem_list[index]; 101 while(pointer) 102 { 103 if((char*)pointer + sizeof(allocMem_ptr_t) == ptr) 104 { 105 if(NULL == pre) 106 allocMem_list[index] = pointer->next; 107 else 108 pre->next = pointer->next; 109 --tableSize; 110 break; 111 } 112 pre = pointer; 113 pointer = pointer->next; 114 } 115 mem_mut.unlock(); 116 free(pointer); 117 } 118 119 void operator delete[](void* pointer) 120 { 121 operator delete(pointer); 122 } 123 124 void operator delete(void* pointer,const char* file,int line) 125 { 126 operator delete(pointer); 127 } 128 void operator delete[](void* pointer,const char* file,int line) 129 { 130 operator delete(pointer); 131 }