00001
00002
00003 #include <stdio.h>
00004 #include <stdlib.h>
00005 #include "MercuryThreads.h"
00006
00007 #include <map>
00008 using namespace std;
00009
00010 void MercuryAMalloc( void * ptr, const char * file, const int line );
00011 void MercuryAFree( void * ptr );
00012
00013
00014
00015 class MercuryMemoryThrough
00016 {
00017 public:
00018 MercuryMemoryThrough() {}
00019 MercuryMemoryThrough( const char * fn, int ln ) { FILENAME=fn; LINENUMBER=ln; }
00020 template< class G >
00021 G * operator << ( G * t ) { MercuryAMalloc( (void*)t, FILENAME, LINENUMBER ); return t; }
00022 template< class G >
00023 G * operator >> ( G * t ) { MercuryAFree( (void*)t ); return t; }
00024 int LINENUMBER;
00025 const char * FILENAME;
00026 } OVERALLFREE;
00027
00029 struct MInfoPair
00030 {
00031 MInfoPair() { }
00032 MInfoPair( const char * f, int l, int s ) { file = f; line = l; size = s; }
00033 const char * file;
00034 int line;
00035 int size;
00036 };
00037
00038 bool bMutexSetUp = false;
00039 COND_MUTEX( MemoryMutex );
00040
00041
00042 map< void *, MInfoPair > * AllMemoryMap = NULL;
00043
00044
00045 void MapFree( void * addy )
00046 {
00047 LOCK_MUTEX( MemoryMutex );
00048
00049 if ( AllMemoryMap == NULL )
00050 AllMemoryMap = new map< void *, MInfoPair >;
00051 if ( AllMemoryMap->find( addy ) == AllMemoryMap->end() )
00052 return;
00053 AllMemoryMap->erase( AllMemoryMap->find( addy ) );
00054
00055 UNLOCK_MUTEX( MemoryMutex );
00056 }
00057
00058
00059 void MapAlloc( void * addy, const char * file, int line, int size )
00060 {
00061 if ( !bMutexSetUp )
00062 {
00063 bMutexSetUp = true;
00064 SETUP_MUTEX( MemoryMutex );
00065 }
00066
00067 LOCK_MUTEX( MemoryMutex );
00068
00069 if ( AllMemoryMap == NULL )
00070 AllMemoryMap = new map< void *, MInfoPair >;
00071 (*AllMemoryMap)[addy] = MInfoPair( file, line, size );
00072
00073 UNLOCK_MUTEX( MemoryMutex );
00074 }
00075
00076 void ResetAllLeakInfo()
00077 {
00078 if ( AllMemoryMap )
00079 {
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093 }
00094 AllMemoryMap = new map< void *, MInfoPair >;
00095 }
00096
00097
00098 void PrintAllLeakInfo()
00099 {
00100 for ( map< void *, MInfoPair >::iterator g = AllMemoryMap->begin(); g != AllMemoryMap->end(); g++ )
00101 printf( "Leak: %p: %s:%d\n", g->first, (g->second).file, (g->second).line );
00102 }
00103
00105 class MemoryWatchForDestroy
00106 {
00107 public:
00108 ~MemoryWatchForDestroy() { if ( Print ) PrintAllLeakInfo(); }
00109 bool Print;
00110 };
00111
00112 MemoryWatchForDestroy DPM;
00113
00114 void SetPrintOnEnd( bool POD )
00115 {
00116 DPM.Print = POD;
00117 }
00118
00119 void * MercuryMalloc( size_t x, const char * file, int line )
00120 {
00121 void * ret = malloc(x);
00122 MapAlloc( ret, file, line, x );
00123 return ret;
00124 }
00125
00126 void * MercuryCalloc( size_t x, size_t y, const char * file, const int line )
00127 {
00128 void * ret = calloc(x,y);
00129 MapAlloc( ret, file, line, x*y );
00130 return ret;
00131 }
00132
00133 void * MercuryRealloc( void * ptr, size_t x, const char * file, const int line )
00134 {
00135 void * ret = realloc(ptr,x);
00136 MapFree( ptr );
00137 MapAlloc( ret, file, line, x );
00138 return ret;
00139 }
00140
00141 void MercuryAMalloc( void * ptr, const char * file, const int line )
00142 {
00143 MapAlloc( ptr, file, line, -1 );
00144 }
00145
00146 void MercuryFree( void * ptr )
00147 {
00148 MapFree( ptr );
00149 free( ptr );
00150 }
00151
00152 void MercuryAFree( void * ptr )
00153 {
00154 MapFree( ptr );
00155 }
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183