Trần Kim Dự
Trần Kim Dự

Reputation: 6102

Memory Allocator : avoid free memory twice

I'm implementing a memory allocator. I currently meet this issue

void deallocate(void* ptr) {
   // code to deallocate memory start at ptr
}

// client test code
printf("Test : deallocate same pointer two times \n");
char* ptr = (char*) allocate(32);
deallocate(ptr);
deallocate(ptr); // ERROR

Because deallocate (by anyway), just free memory at pointer ptr. Address stores in ptr still like before, and I cannot set it to NULL (because parameter is a pointer, not a pointer of a pointer).

So my question is : how can I prevent allocated same pointer twice as above scene ?

Thanks :)

Upvotes: 0

Views: 410

Answers (3)

galinette
galinette

Reputation: 9292

Allocators does not prevent this. It's not the responsibility of the allocator, but the allocator user, to care for double deletion.

If you REALLY want your deallocator to have this kind of fool-proof mechanism, you need to store a table of all allocated pointers in a global variable in your allocator implementation. Then the deallocator would first check if the pointer is registered, and if yes, deallocate and remove the pointer from the table. Off course you will need a very efficient container for the table, with low complexity for insertions, deletions, and lookup.

Upvotes: 2

Pranit Kothari
Pranit Kothari

Reputation: 9841

As soon as you deallocate memory, NULL the pointer, if you call free on NULL pointer, there will be no exception,

Like,

deallocate(ptr);
ptr = NULL; 
deallocate(ptr); // NO ERROR

Upvotes: 0

Nik Bougalis
Nik Bougalis

Reputation: 10613

If you want to prevent one solution is to track all addresses that have been passed to your version of free: When free is called, you first check whether ptr has already been passed to you (e.g. by searching for that key in a map/hash table). If it is present, you do nothing; otherwise you an entry for ptr into the data structure and proceed to do whatever you need to do.

Of course, it's not quite so simple: you need to also remove the ptr from the data structure when you do allocations. If you allocate size bytes at address addr then you need to remove ptr if addr <= ptr <= addr+size.

Assuming you're implementing any sort of sensible memory manager however, you will already maintain a free pool (a list of blocks that are either not allocated or were allocated and have been freed) and perhaps even a linked list of allocated blocks.

In which case, you can simply traverse the free pool to see if the block being freed is already listed in the free pool and if so, do nothing. Or, alternatively, iterate the list of allocated blocks and ensure that what you're being asked to free was indeed allocated.

Of course, as someone else already noted, this is typically the responsibility of the caller and not the allocator, although having this sort of functionality in an allocator is useful for debugging purposes.

Upvotes: 1

Related Questions