Reputation: 501
It is known that if we pass a pointer by value to a function, it cannot be freed inside the function, like so:
void func(int *p)
{
free(p);
p = NULL;
}
p holds a copy of a (presumably valid) address, so free(p) tries to, well, free it. But since it is a copy, it cannot really free it. How does the call to free() know that it cannot really free it ?
The code above does not produce an error. Does that mean free() just fails silently, "somehow" knowing that address passed in as argument cannot be worked upon ?
Upvotes: 5
Views: 7897
Reputation: 3353
What everybody is saying is that your memory will be freed by free(p);
, but your original pointer (which you use to call the function with) will still hold the (now invalid) address. If a new block of memory including your address is allocated at a later stage than your original pointer will become valid (for memory manager) again, but will now point to completely different data causing all sorts of problems and confusion.
Upvotes: 1
Reputation: 12688
Passing p
to func()
by value, which will copy the pointer and creates the local copy to func()
which frees the memory. func()
then sets it's own instance of the pointer p
to NULL
but which is useless. Once the function is complete the parameter p
come to end of existence. In calling function you still have pointer p
holding an address, but the block is now on the free list and not useful for storage until allocated again.
Upvotes: 2
Reputation: 19104
The only problem is if this function is in a different DLL (Windows). Then, it may be linked with a different version of the standard library and have different ideas on how the heap is built.
Otherwise no problem.
Upvotes: 2
Reputation: 4487
No you really free the block of memory. After the function call, the pointer passed to this function is pointing to nowhere : same address but the MMU don't know anymore what to do with this address
Upvotes: 0
Reputation:
p holds a copy of a (presumably valid) address, so free(p) tries to, well, free it. But since it is a copy, it cannot really free it.
It's not true. free()
can work just fine if p
is a valid address returned by malloc()
(or NULL
).
In fact, this is a common pattern for implementing custom "destructor" functions (when writing OO-style code in C).
What you probably mean is that p
won't change to NULL
after this - but that's natural, since you're passing it by value. If you want to free()
and null out the pointer, then pass it by pointer ("byref"):
void func(int **p)
{
if (p != NULL) {
free(*p);
*p = NULL;
}
}
and use this like
int *p = someConstructor();
func(&p);
// here 'p' will actually be NULL
Upvotes: 23