Miranda里使用专门的函数分配和释放内存,分配内存的时候总是在前面多分配三个DWORD(12 bytes),
第一个DWORD用于存储内存块的大小(不包括这三个附加的DWORD)
第二个和第三个DWORD用于描述这块内存的使用状态:BLOCK_ALLOCED 或 BLOCK_FREED
void* mir_alloc( size_t size )
{
if ( size == 0 )
return NULL;
{
char* p = (char*)malloc( size + sizeof(DWORD)*3 );
if ( p == NULL ) {
OutputDebugStringA( "memory overflow/n" );
#if defined( _DEBUG )
DebugBreak();
#endif
return NULL;
}
*( DWORD* )p = ( DWORD )size;
*( DWORD* )&p[ sizeof(DWORD) ] = BLOCK_ALLOCED;
*( DWORD* )&p[ size + sizeof(DWORD)*2 ] = BLOCK_ALLOCED;
return p + sizeof( DWORD )*2;
}
}
void mir_free( void* ptr )
{
char* p;
DWORD size;
if ( ptr == NULL )
return;
if ( !CheckBlock( ptr ))
return;
p = ( char* )ptr - sizeof(DWORD)*2;
size = *( DWORD* )p;
*( DWORD* )&p[ sizeof(DWORD) ] = BLOCK_FREED;
*( DWORD* )&p[ size + sizeof(DWORD)*2 ] = BLOCK_FREED;
free( p );
}
void* mir_realloc( void* ptr, size_t size )
{
char* p;
if ( ptr != NULL ) {
if ( !CheckBlock( ptr ))
return NULL;
p = ( char* )ptr - sizeof(DWORD)*2;
}
else p = NULL;
p = ( char* )realloc( p, size + sizeof(DWORD)*3 );
if ( p == NULL ) {
OutputDebugStringA( "memory overflow/n" );
#if defined( _DEBUG )
DebugBreak();
#endif
return NULL;
}
*( DWORD* )p = ( DWORD )size;
*( DWORD* )&p[ sizeof(DWORD) ] = BLOCK_ALLOCED;
*( DWORD* )&p[ size + sizeof(DWORD)*2 ] = BLOCK_ALLOCED;
return p + sizeof( DWORD )*2;
}
static int CheckBlock( void* blk )
{
int result = FALSE;
char* p = ( char* )blk - sizeof(DWORD)*2;
DWORD size, *b, *e;
__try
{
size = *( DWORD* )p;
b = ( DWORD* )&p[ sizeof( DWORD ) ];
e = ( DWORD* )&p[ sizeof( DWORD )*2 + size ];
if ( *b != BLOCK_ALLOCED || *e != BLOCK_ALLOCED )
{
if ( *b == BLOCK_FREED && *e == BLOCK_FREED )
OutputDebugStringA( "memory block is already deleted/n" );
else
OutputDebugStringA( "memory block is corrupted/n" );
#if defined( _DEBUG )
DebugBreak();
#endif
}
else result = TRUE;
}
__except( EXCEPTION_EXECUTE_HANDLER )
{
OutputDebugStringA( "access violation during checking memory block/n" );
#if defined( _DEBUG )
DebugBreak();
#endif
}
return result;
}