00001
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifdef MEMCHK
00027
00028 int blockNum = 0;
00029 int operationID = 0;
00030 int errorNum = 0;
00031 int breakOnFree = 0;
00032 const int infoblocksize = 3;
00033
00034 bool memchk_initialized = false;
00035
00036
00037 bool memchk_reallyComplete = false;
00038 int memchk_breakOnOp = -1;
00039
00040 void memchkError ( )
00041 {
00042 errorNum++;
00043 fprintf(stderr, "memchkError !\n");
00044 }
00045
00046 class Block {
00047 public:
00048 int start;
00049 int stop;
00050 int userStart;
00051 int size;
00052 int allocated;
00053 int freed;
00054 int allocatedOP;
00055 int freedOP;
00056 };
00057
00058
00059 Block blocks[1000000];
00060
00061 void* verifyblock ( int tp, Block* b )
00062 {
00063 int error = 0;
00064 int* tmpi = (int*) b->start;
00065
00066 if ( tp != -1 )
00067 if ( tmpi[0] != tp )
00068 error++;
00069
00070
00071
00072
00073
00074
00075
00076
00077 int amt = tmpi[2];
00078
00079 for ( int i = 0; i < 25; i++ ) {
00080 if ( tmpi[infoblocksize + i] != 0x12345678) {
00081 memchkError();
00082 #ifdef logging
00083 logtofile ( "memory check: verifyblock : error C at address %x", p );
00084 #endif
00085 }
00086
00087 if ( tmpi[infoblocksize + i + (amt+3)/4 + 25] != 0x87654321 ) {
00088 memchkError();
00089 #ifdef logging
00090 logtofile ( "memory check: verifyblock : error D at address %x", p );
00091 #endif
00092 }
00093 }
00094 return tmpi;
00095 }
00096
00097 void verifyallblocks ( void )
00098 {
00099 for ( int i = 0; i < blockNum; i++ )
00100 if ( !blocks[i].freed )
00101 verifyblock ( -1, &blocks[i] );
00102 }
00103
00104 void* memchkAlloc ( int tp, size_t amt )
00105 {
00106 if ( ! memchk_initialized ) {
00107 memset ( blocks, 0, sizeof ( blocks ));
00108 memchk_initialized = true;
00109 }
00110
00111 if ( memchk_reallyComplete )
00112 verifyallblocks();
00113
00114 Block& b = blocks[ blockNum++ ];
00115 if ( blockNum >= 1000000 )
00116 memchkError();
00117
00118 b.size = amt + (50+infoblocksize) * 4;
00119 b.allocated++;
00120
00121 if ( operationID == memchk_breakOnOp )
00122 memchkError();
00123
00124 b.allocatedOP = operationID++;
00125
00126 void* tmp = malloc ( b.size+4 );
00127
00128
00129 b.start = (int) tmp;
00130 b.stop = b.start + b.size;
00131
00132 for ( int i = 0; i < blockNum-1; i++ ) {
00133 if ( !blocks[i].freed ) {
00134 if ( b.start >= blocks[i].start && b.start < blocks[i].stop )
00135 memchkError();
00136 if ( b.stop >= blocks[i].start && b.stop < blocks[i].stop )
00137 memchkError();
00138 if ( blocks[i].start < b.start && blocks[i].stop > b.stop )
00139 memchkError();
00140 }
00141 }
00142
00143
00144 int* tmpi = (int*) tmp;
00145
00146
00147
00148
00149 tmpi[0] = tp;
00150
00151 if ( 4 < infoblocksize )
00152 tmpi[4] = (int) tmp;
00153
00154 if ( 2 < infoblocksize )
00155 tmpi[2] = amt;
00156
00157 if ( 3 < infoblocksize )
00158 tmpi[3] = b.allocatedOP;
00159
00160 if ( 1 < infoblocksize )
00161 tmpi[1] = blockNum-1;
00162
00163 for ( int i = 0; i < 25; i++ ) {
00164 tmpi[infoblocksize + i] = 0x12345678;
00165 tmpi[infoblocksize + i + (amt+3)/4 + 25] = 0x87654321;
00166 }
00167 void* p = &tmpi[25+infoblocksize];
00168 b.userStart = (int) p;
00169 return p;
00170 }
00171
00172 void memchkFree ( int tp, void* buf )
00173 {
00174 if ( breakOnFree == (int) buf )
00175 memchkError();
00176
00177 Block* b = NULL;
00178 for ( int i = blockNum-1; i>= 0 ; i-- )
00179 if ( blocks[i].userStart == (int) buf ) {
00180 b = &blocks[i];
00181 break;
00182 }
00183
00184 if ( b ) {
00185
00186 if ( memchk_reallyComplete )
00187 verifyallblocks();
00188
00189 void* tmpi = verifyblock ( tp, b );
00190
00191 if ( b->freed > 0 )
00192 memchkError();
00193
00194 if ( b->allocated <= 0 )
00195 memchkError();
00196
00197 if ( operationID == memchk_breakOnOp )
00198 memchkError();
00199
00200
00201 b->freed++;
00202 b->freedOP = operationID++;
00203
00204 free ( tmpi );
00205 } else
00206 free ( buf );
00207 }
00208
00209
00210
00211
00212
00213 void *operator new( size_t amt )
00214 {
00215 return( memchkAlloc( 100, amt ) );
00216 }
00217
00218 void operator delete( void *p )
00219 {
00220 if ( p )
00221 memchkFree( 100, p );
00222 }
00223
00224 void *operator new []( size_t amt )
00225 {
00226 return( memchkAlloc( 102, amt ) );
00227 }
00228
00229 void operator delete []( void *p )
00230 {
00231 if ( p )
00232 memchkFree( 102, p );
00233 }
00234
00235 void* asc_malloc ( size_t size )
00236 {
00237 void* tmp = memchkAlloc ( 104, size );
00238 return tmp;
00239 }
00240
00241 void asc_free ( void* p )
00242 {
00243 memchkFree ( 104, p );
00244 }
00245
00246 #else
00247
00248 void* asc_malloc ( size_t size )
00249 {
00250 void* tmp = malloc ( size );
00251 #ifdef _DOS_
00252 if ( tmp == NULL )
00253 new_new_handler();
00254 #else
00255 if ( tmp == NULL )
00256 fatalError("Out of memory!");
00257 #endif
00258 return tmp;
00259 }
00260
00261 void asc_free ( void* p )
00262 {
00263 free ( p );
00264 }
00265
00266
00267 #endif