static void memmgr_final (void) { struct block *block = block_first; struct unit_head_large *large = unit_head_large_first; #ifdef LOG_MEMMGR int count = 0; #endif /* LOG_MEMMGR */ while (block) { if (block->unit_used) { int i; for (i = 0; i < block->unit_maxused; i++) { struct unit_head *head = block2unit (block, i); if (head->block != NULL) { char *ptr = (char *) head + sizeof (struct unit_head) - sizeof (long); #ifdef LOG_MEMMGR char buf[1024]; sprintf (buf, "%04d : %s line %d size %lu address 0x%p\n", ++count, head->file, head->line, (unsigned long) head->size, ptr); memmgr_log (buf); #endif /* LOG_MEMMGR */ // get block pointer and free it [celest] _mfree (ptr, ALC_MARK); } } } block = block->block_next; } while (large) { struct unit_head_large *large2; #ifdef LOG_MEMMGR char buf[1024]; sprintf (buf, "%04d : %s line %d size %lu address 0x%p\n", ++count, large->unit_head.file, large->unit_head.line, (unsigned long) large->size, &large->unit_head.checksum); memmgr_log (buf); #endif /* LOG_MEMMGR */ large2 = large->next; FREE (large, file, line, func); large = large2; } #ifdef LOG_MEMMGR if (count == 0) { ShowInfo ("Memory manager: No memory leaks found.\n"); } else { ShowWarning ("Memory manager: Memory leaks found and fixed.\n"); fclose (log_fp); } #endif /* LOG_MEMMGR */ }
static void memmgr_final (void) { struct block *block = block_first; struct chunk *chunk = chunk_first, *chunk2; struct unit_head_large *large = unit_head_large_first, *large2; int i; #ifdef LOG_MEMMGR int count = 0; char buf[128]; #endif while (block) { if (block->unit_size) { for (i = 0; i < block->unit_count; i++) { struct unit_head *head = (struct unit_head*)(&block->data[block->unit_size * i]); if(head->block != NULL) { #ifdef LOG_MEMMGR sprintf (buf, "%04d : %s line %d size %d\n", ++count, head->file, head->line, head->size); memmgr_log (buf); #endif // get block pointer and free it [celest] _mfree ((char *)head + sizeof(struct unit_head) - sizeof(int), ALC_MARK); } } } //if (block->block_no >= block2->block_no + BLOCK_ALLOC - 1) { // reached a new block array //block = block->block_next; /* Okay wise guys... this is how block2 was allocated: [Skotlex] struct block* p; char *pb = (char *) CALLOC (sizeof(struct block),BLOCK_ALLOC + 1); pb += sizeof(struct block) - ((unsigned long)pb % sizeof(struct block)); p = (struct block*)pb; The reason we get an invalid pointer is that we allocated pb, not p. So how do you get pb when you only have p? The answer is, you can't, because the original pointer was lost when memory-aligning the block. So we either forget this FREE or use a self-reference... Since we are already quitting, it might be ok to just not free the block as it is. */ // didn't realise that before o.o -- block chunks are now freed below [celest] // FREE(block2); //block2 = block; //continue; //} block = block->block_next; } // free the allocated block chunks chunk = chunk_first; while (chunk) { chunk2 = chunk->next; FREE(chunk->block,file,line,func); FREE(chunk,file,line,func); chunk = chunk2; } while(large) { large2 = large->next; #ifdef LOG_MEMMGR sprintf (buf, "%04d : %s line %d size %d\n", ++count, large->unit_head.file, large->unit_head.line, large->unit_head.size); memmgr_log (buf); #endif FREE(large,file,line,func); large = large2; } #ifdef LOG_MEMMGR if(count == 0) { ShowInfo("Memory manager: No memory leaks found.\n"); } else { ShowWarning("Memory manager: Memory leaks found and fixed.\n"); fclose(log_fp); } #endif return; }