home *** CD-ROM | disk | FTP | other *** search
- #include "safe_new.h"
-
- #ifdef SAFE_NEW
-
- #undef new
- #undef delete
-
- #include <win32/windows.h> // For HFILE
- #include <memory>
- #include <SimpleList.h>
-
- struct MemNode : public SimpleListNode<MemNode>
- {
- static const unsigned nice_crc;
-
- const char * file;
- unsigned line;
- unsigned size;
- unsigned crc;
-
- bool test_validity()
- {
- unsigned fint = reinterpret_cast<unsigned>( file );
- return (line + size + fint + crc) == nice_crc;
- }
- void make_valid()
- {
- unsigned fint = reinterpret_cast<unsigned>( file );
- crc = nice_crc - (line + size + fint);
- }
- void make_invalid()
- {
- unsigned fint = reinterpret_cast<unsigned>( file );
- crc = (line + size + fint);
- }
- };
- const unsigned MemNode::nice_crc = ('N' << 24) + ('i' << 16) + ('c' << 8) + 'e';
-
- static MemNode * start;
- static char * start_place[ sizeof(MemNode) ];
-
- static int simple_counter = 0;
-
- class RepFile
- {
- HANDLE hfile;
- public:
- explicit RepFile(bool create)
- {
- hfile = CreateFile( "memory.log", GENERIC_WRITE, FILE_SHARE_WRITE, NULL, create ? CREATE_ALWAYS : OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL );
- if( hfile != INVALID_HANDLE_VALUE && !create )
- {
- SetFilePointer( hfile, 0, NULL, FILE_END );
- }
- }
- ~RepFile()
- {
- if( hfile != INVALID_HANDLE_VALUE )
- CloseHandle( hfile );
- }
- void write( const char * str )const
- {
- if( hfile == INVALID_HANDLE_VALUE )
- return;
- DWORD read = 0;
- WriteFile( hfile, str, strlen(str), &read, NULL );
- }
- };
-
- int MemoryLeakReporterCreator::ref_count = 0;
-
- MemoryLeakReporterCreator::MemoryLeakReporterCreator()
- {
- if( ++ref_count == 1 )
- {
- }
- }
-
- MemoryLeakReporterCreator::~MemoryLeakReporterCreator()
- {
- if( --ref_count == 0 )
- {
- MemNode * curr = start->get_next();
-
- RepFile rep_file( false );
- rep_file.write( "Memory leaks:\n addr | size | line | file\n---------+---------+------+----------\n" );
- for( ; curr ; curr = curr->get_next() )
- {
- char buff[1024];
- int bs = wsprintf( buff,"%8X |%8d |%5d | %s\n", reinterpret_cast<unsigned>( curr ), curr->size, curr->line, curr->file );
- rep_file.write( buff );
- }
- }
- }
-
-
- static void * our_alloc( size_t s, const char * file, int line )
- {
- void * mama = malloc( s + sizeof(MemNode) );
- if( mama == 0 )
- {
- throw std::bad_alloc();
- }
- if( !start )
- {
- start = new(start_place) MemNode;
- RepFile rep_file( true );
- rep_file.write( "Twice deleted:\n addr | size | line | file\n---------+---------+------+----------\n" );
- }
- ++simple_counter;
-
- char * chama = (char *)mama;
- MemNode * just = new(mama) MemNode; // in-place new
- if( just == (void *)0x00851AD0 )
- just = just;
-
- just->file = file;
- just->line = line;
- just->size = s;
- just->make_valid();
-
- just->link( start );
-
- void * p = (void *)( chama + sizeof(MemNode) );
- return p;
- }
-
- static const char * CurrentFile = 0;
- static int CurrentLine = 0;
-
- void memory_leak_report_delete( const char * cf, int cl )
- {
- CurrentFile = cf;
- CurrentLine = cl;
- }
-
- static void report_bad_delete( unsigned addr, unsigned size, unsigned line, const char * file )
- {
- RepFile rep_file( false );
- char buff[1024];
- int bs = wsprintf( buff,"%8X |%8d |%5d | %s\n", addr, size, line, file );
- rep_file.write( buff );
- bs = wsprintf( buff," In: |%5d | %s\n", CurrentLine, CurrentFile );
- rep_file.write( buff );
- }
-
- static void our_free( void * p, const char * file, int line )
- {
- if( p == 0 )
- {
- CurrentFile = 0;
- CurrentLine = 0;
- return;
- }
- char * chama = (char *)p - sizeof(MemNode);
- void * mama = chama;
- MemNode * just = (MemNode *)mama;
-
- try
- {
- if( !just->test_validity() )
- {
- report_bad_delete( reinterpret_cast<unsigned>( p ), just->size, just->line, just->file );
- CurrentFile = 0;
- CurrentLine = 0;
- return;
- }
- just->make_invalid();
- just->unlink();
-
- free( mama );
- }
- catch(...) // Invalid address dereference, really
- {
- report_bad_delete( reinterpret_cast<unsigned>( p ), 0, 0, "Exception occured, trying to delete the memory at this address");
- CurrentFile = 0;
- CurrentLine = 0;
- return;
- }
- CurrentFile = 0;
- CurrentLine = 0;
- --simple_counter;
- }
-
- void * __cdecl operator new( size_t s, const char * file, int line )
- {
- return our_alloc( s, file, line );
- }
-
- void __cdecl operator delete( void * p, const char * file, int line )
- {
- our_free( p, file, line );
- }
-
- void * __cdecl operator new( size_t s )
- {
- return operator new( s, "Runtime", 0 );
- }
-
- void __cdecl operator delete( void * p )
- {
- operator delete( p, "Runtime", 0 );
- }
-
- void * __cdecl operator new[]( size_t s )
- {
- return operator new( s );
- }
-
- void __cdecl operator delete[]( void * p )
- {
- operator delete( p );
- }
-
- void * __cdecl operator new[]( size_t s, const char * file, int line )
- {
- return operator new( s, file, line );
- }
-
- void __cdecl operator delete[]( void * p, const char * file, int line )
- {
- operator delete( p, file, line );
- }
-
- #endif