开发者

Why is my pointer not null after free?

void getFree(void *ptr)
{
    if(ptr != NULL)
    {
        free(ptr);
        ptr = NULL;
    }
    return;
}
int main()
{
char *a;
a=mal开发者_开发问答loc(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;
}


The question has already been answered but if it helps, I can explain it graphically.

You are doing this --> the pointer is copied by value to your function so it points to the array

but instead you want this -->point to the original pointer

As Merlyn Morgan-Graham already said, the way to solve it is to add operators * and &.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜