简体   繁体   中英

dereferencing freed pointer in C

int** array = (int**) malloc(1*sizeof(int*));
int* int_in_array = (int*) malloc(1*sizeof(int));
*int_in_array = 6
array[0] = int_in_array;

and suppose I do

free(array)

can I still rely on the fact that *int_in_array will give me 6?

Now suppose in addition, I do

free(array[0])

then, can I still rely on the fact that *int_in_array will give me 6 since int_in_array still points to 6?

thanks so much!

You seem to somehow have a mental model where you expect pointers to be magically supervised, so that one pointer shold "know" what happens to another.

That's not how pointers, or the C memory model, work at all.

There is no connection between different pointers. If two pointers point at the same address, and you free() one of them, the other one becomes invalid but it's value doesn't change . Neither does the value of the first; it's just that dereferencing either of them just became an invalid thing to do.

Consider this:

int *a = malloc(sizeof *a);

if(a != NULL)
{
  int *b = a;
  *a = 4711;

  printf("a=%p\nb=%p\n", (void *) a, (void *) b);
  free(b);  /* same pointer that malloc() returned, this is fine */
  printf("a=%p\nb=%p\n", (void *) a, (void *) b);
}

The above will print the same address four times, since the value of any of the pointers doesn't change just because you call free() on one of them. Remember that free() is not magic, it's just a function. There is no special hidden functionality with it, you can write your own malloc() and free() if you feel like it and get the exact same semantics.

int** array = (int**) malloc(1*sizeof(int*));
int* int_in_array = (int*) malloc(1*sizeof(int));
*int_in_array = 6
array[0] = int_in_array;

after doing free(array) you can still access and use int_in_array . But you cannot call free(array[0]) afterwards because you cannot use array any more.

If you don't call free(array) but just free(array[0]) , you cannot use *int_in_array because you freed the memory.

  1. 6 is stored in the memory that is pointed to by int * int_in_array .

    So if you free() this memory (by doing free(int_in_array) ) the 6 is gone, or at least not accessible anymore without provoking undefined behavior.

  2. In the memory that is pointed to by array a copy of the value of int_in_array is stored. So free() ing this copy by calling free(array) does not affect what is stored in int_in_array . And also in no way the memory this value points to is affected.

    The data pointed to by array can be accessed directly by either doing *array or by doing array[0] . As it stores the copy of int_in_array doing free(array[0] is the same as doing free(int_in_array) . with the same results on accessing 6 as mentioned under 1.

When you call free(array) , int_in_array is still guaranteed to point to a piece of memory containing 6 . array itself may or may not continue pointing to int_in_array depending on whether the memory it used to occupy was needed somewhere else, or a whole host of other circumstances.

When you call free(int_in_array) , you are telling the system that you do not require the memory containing 6 any longer. The pointer value will still be the same, but you are no longer guaranteed that 6 will still be the value stored at that location.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM