?? ftdbgmem.c
字號:
} static FT_MemNode* ft_mem_table_get_nodep( FT_MemTable table, FT_Byte* address ) { FT_ULong hash; FT_MemNode *pnode, node; hash = FT_MEM_VAL( address ); pnode = table->buckets + ( hash % table->size ); for (;;) { node = pnode[0]; if ( !node ) break; if ( node->address == address ) break; pnode = &node->link; } return pnode; } static void ft_mem_table_set( FT_MemTable table, FT_Byte* address, FT_ULong size ) { FT_MemNode *pnode, node; if ( table ) { pnode = ft_mem_table_get_nodep( table, address ); node = *pnode; if ( node ) { if ( node->size < 0 ) { /* this block was already freed. This means that our memory is */ /* now completely corrupted! */ ft_mem_debug_panic( "memory heap corrupted (allocating freed block)" ); } else { /* this block was already allocated. This means that our memory */ /* is also corrupted! */ ft_mem_debug_panic( "memory heap corrupted (re-allocating allocated block)" ); } } /* we need to create a new node in this table */ node = (FT_MemNode)ft_mem_table_alloc( table, sizeof ( *node ) ); if ( node == NULL ) ft_mem_debug_panic( "not enough memory to run memory tests" ); node->address = address; node->size = size; node->alloc_file_name = table->file_name; node->alloc_line_no = table->line_no; node->free_file_name = NULL; node->free_line_no = 0; node->link = pnode[0]; pnode[0] = node; table->nodes++; table->alloc_total += size; table->alloc_current += size; if ( table->alloc_current > table->alloc_max ) table->alloc_max = table->alloc_current; if ( table->nodes * 3 < table->size || table->size * 3 < table->nodes ) ft_mem_table_resize( table ); } } static void ft_mem_table_remove( FT_MemTable table, FT_Byte* address ) { if ( table ) { FT_MemNode *pnode, node; pnode = ft_mem_table_get_nodep( table, address ); node = *pnode; if ( node ) { if ( node->size < 0 ) ft_mem_debug_panic( "freeing memory block at %p more than once at (%s:%ld)\n" "block allocated at (%s:%ld) and released at (%s:%ld)", address, FT_FILENAME( table->file_name ), table->line_no, FT_FILENAME( node->alloc_file_name ), node->alloc_line_no, FT_FILENAME( node->free_file_name ), node->free_line_no ); /* we simply invert the node's size to indicate that the node */ /* was freed. We also change its contents. */ FT_MEM_SET( address, 0xF3, node->size ); table->alloc_current -= node->size; node->size = -node->size; node->free_file_name = table->file_name; node->free_line_no = table->line_no; } else ft_mem_debug_panic( "trying to free unknown block at %p in (%s:%ld)\n", address, FT_FILENAME( table->file_name ), table->line_no ); } } extern FT_Pointer ft_mem_debug_alloc( FT_Memory memory, FT_Long size ) { FT_MemTable table = (FT_MemTable)memory->user; FT_Byte* block; if ( size <= 0 ) ft_mem_debug_panic( "negative block size allocation (%ld)", size ); block = (FT_Byte *)ft_mem_table_alloc( table, size ); if ( block ) ft_mem_table_set( table, block, (FT_ULong)size ); table->file_name = NULL; table->line_no = 0; return (FT_Pointer) block; } extern void ft_mem_debug_free( FT_Memory memory, FT_Pointer block ) { FT_MemTable table = (FT_MemTable)memory->user; if ( block == NULL ) ft_mem_debug_panic( "trying to free NULL in (%s:%ld)", FT_FILENAME( table->file_name ), table->line_no ); ft_mem_table_remove( table, (FT_Byte*)block ); /* we never really free the block */ table->file_name = NULL; table->line_no = 0; } extern FT_Pointer ft_mem_debug_realloc( FT_Memory memory, FT_Long cur_size, FT_Long new_size, FT_Pointer block ) { FT_MemTable table = (FT_MemTable)memory->user; FT_MemNode node, *pnode; FT_Pointer new_block; const char* file_name = FT_FILENAME( table->file_name ); FT_Long line_no = table->line_no; if ( block == NULL || cur_size == 0 ) ft_mem_debug_panic( "trying to reallocate NULL in (%s:%ld)", file_name, line_no ); if ( new_size <= 0 ) ft_mem_debug_panic( "trying to reallocate %p to size 0 (current is %ld) in (%s:%ld)", block, cur_size, file_name, line_no ); /* check 'cur_size' value */ pnode = ft_mem_table_get_nodep( table, (FT_Byte*)block ); node = *pnode; if ( !node ) ft_mem_debug_panic( "trying to reallocate unknown block at %p in (%s:%ld)", block, file_name, line_no ); if ( node->size <= 0 ) ft_mem_debug_panic( "trying to reallocate freed block at %p in (%s:%ld)", block, file_name, line_no ); if ( node->size != cur_size ) ft_mem_debug_panic( "invalid ft_realloc request for %p. cur_size is " "%ld instead of %ld in (%s:%ld)", block, cur_size, node->size, file_name, line_no ); new_block = ft_mem_debug_alloc( memory, new_size ); if ( new_block == NULL ) return NULL; ft_memcpy( new_block, block, cur_size < new_size ? cur_size : new_size ); table->file_name = file_name; table->line_no = line_no; ft_mem_debug_free( memory, (FT_Byte*)block ); return new_block; } extern FT_Int ft_mem_debug_init( FT_Memory memory ) { FT_MemTable table; FT_Int result = 0; if ( getenv( "FT_DEBUG_MEMORY" ) ) { table = ft_mem_table_new( memory ); if ( table ) { memory->user = table; memory->alloc = ft_mem_debug_alloc; memory->realloc = ft_mem_debug_realloc; memory->free = ft_mem_debug_free; result = 1; } } return result; } extern void ft_mem_debug_done( FT_Memory memory ) { FT_MemTable table = (FT_MemTable)memory->user; if ( table ) { memory->free = table->free; memory->realloc = table->realloc; memory->alloc = table->alloc; ft_mem_table_destroy( table ); memory->user = NULL; } } FT_BASE_DEF( FT_Error ) FT_Alloc_Debug( FT_Memory memory, FT_Long size, void* *P, const char* file_name, FT_Long line_no ) { FT_MemTable table = (FT_MemTable)memory->user; if ( table ) { table->file_name = file_name; table->line_no = line_no; } return FT_Alloc( memory, size, P ); } FT_BASE_DEF( FT_Error ) FT_Realloc_Debug( FT_Memory memory, FT_Long current, FT_Long size, void* *P, const char* file_name, FT_Long line_no ) { FT_MemTable table = (FT_MemTable)memory->user; if ( table ) { table->file_name = file_name; table->line_no = line_no; } return FT_Realloc( memory, current, size, P ); } FT_BASE_DEF( void ) FT_Free_Debug( FT_Memory memory, FT_Pointer block, const char* file_name, FT_Long line_no ) { FT_MemTable table = (FT_MemTable)memory->user; if ( table ) { table->file_name = file_name; table->line_no = line_no; } FT_Free( memory, (void **)block ); }#else /* !FT_DEBUG_MEMORY */ /* ANSI C doesn't like empty source files */ const FT_Byte _debug_mem_dummy = 0;#endif /* !FT_DEBUG_MEMORY *//* END */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -