Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is my pointer not null after free?

Tags:

c

free

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?

like image 827
Jeegar Patel Avatar asked Sep 30 '11 09:09

Jeegar Patel


4 Answers

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;
}
like image 76
Merlyn Morgan-Graham Avatar answered Nov 15 '22 21:11

Merlyn Morgan-Graham


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);
}
like image 21
Vilx- Avatar answered Nov 15 '22 20:11

Vilx-


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; }
like image 5
Roman R. Avatar answered Nov 15 '22 20:11

Roman R.


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..

like image 3
wormsparty Avatar answered Nov 15 '22 20:11

wormsparty