void getFree(void *ptr)
{
if(ptr != NULL)
{
free(ptr);
ptr = NULL;
}
return;
}
int main()
{
char *a;
a=malloc(10);
getFree(a);
if(a==NULL)
printf("it is null");
else
printf("not null");
}
Why is the output of this program not NULL?
Because the pointer is copied by value to your function. You are assigning NULL
to the local copy of the variable (ptr
). This does not assign it to the original copy.
The memory will still be freed, so you can no longer safely access it, but your original pointer will not be NULL
.
This the same as if you were passing an int
to a function instead. You wouldn't expect the original int
to be edited by that function, unless you were passing a pointer to it.
void setInt(int someValue) {
someValue = 5;
}
int main() {
int someOtherValue = 7;
setInt(someOtherValue);
printf("%i\n", someOtherValue); // You'd expect this to print 7, not 5...
return 0;
}
If you want to null the original pointer, you'll have to pass a pointer-to-pointer:
void getFree(void** ptr) {
/* Note we are dereferencing the outer pointer,
so we're directly editing the original pointer */
if (*ptr != NULL) {
/* The C standard guarantees that free() safely handles NULL,
but I'm leaving the NULL check to make the example more clear.
Remove the "if" check above, in your own code */
free(*ptr);
*ptr = NULL;
}
return;
}
int main() {
char *a;
a = malloc(10);
getFree(&a); /* Pass a pointer-to-pointer */
if (a == NULL) {
printf("it is null");
} else {
printf("not null");
}
return 0;
}
Because the getFree()
function takes a copy of the pointer. ptr
and c
are both pointers, but they are different variables. It's the same reason why this function will output "6":
void Magic(int x)
{
x = 1;
}
void main()
{
int a = 6;
Magic(a);
printf("%d", a);
}
You are passing pointer a
by value, so it is not modified by function. It's only a copy of pointer modified within function, the original variable value is not affected.
Update:
If you wanted to make your life easier by replacing freeing + nulling a variable with a single line of code, you need either a macro:
#define MYFREE(x) free(x); x = NULL;
or a function with pointer to pointer argument:
void myfree(void** pp) { free(*pp); *pp = NULL; }
Pointers are stored as integers somewhere in memory.
When you do a = malloc(10);
, a
has some value, say 0x1.
When you call getFree(a);
, the function copies a
into void *ptr
.
Now a=0x1
and ptr=0x1
.
When you do ptr=NULL
, only ptr
is changed to NULL, but a
is still 0x1..
You are passing the pointer By value.. (By default C passes the argument by value) which means you are updating the copy only ..not the real location..for that you might need to use pointer to pointer in C
void getFree(void **ptr)
{
if(*ptr != NULL)
{
free(*ptr);
*ptr = NULL;
}
return;
}