Reputation: 6102
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
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
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
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