15
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?

undur_gongor
  • 15,657
  • 5
  • 63
  • 75
Jeegar Patel
  • 26,264
  • 51
  • 149
  • 222

6 Answers6

27

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;
}
Merlyn Morgan-Graham
  • 58,163
  • 16
  • 128
  • 183
7

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);
}
Vilx-
  • 104,512
  • 87
  • 279
  • 422
5

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; }
Roman R.
  • 68,205
  • 6
  • 94
  • 158
3

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

wormsparty
  • 2,481
  • 19
  • 31
1

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

Community
  • 1
  • 1
alepaff
  • 63
  • 6
1

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;
}
Aman Agarwal
  • 727
  • 6
  • 15