Why is my pointer not null after free?

2019-01-23 07:50发布

问题:

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?

回答1:

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;
}


回答2:

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);
}


回答3:

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; }


回答4:

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



回答5:

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;
}


标签: c free