CASE 1
Caller:
void *allocated = malloc(100);
xfree(allocated);
Subroutine:
void xfree(void *ptr);
Situation:
allocated -> [memory] <- ptr
you can free memory but you can't change *allocated* variable
CASE 2 (correct)
Caller:
void *allocated = malloc(100);
xfree(&allocated); <- note the '&' sign, an address of *allocated* variable
Subroutine:
void xfree(void **ptr); <- again, ptr contains an address of *allocated* variable
Situation:
allocated -> [memory]
^
|
ptr
ptr points to *allocated* variable, which points to [memory] so we can control both:
free(*ptr);
*ptr = NULL; <- chaning the value of *allocated* to NULL: *SUCCESS*