How do pointers assigned to pointers and free() work together?

After

int *p = malloc(sizeof(int));
              x
            +----+
p --------> |    |
            +----+

P is pointing to some x memory which holds the some junk data.

*p = 10;

You are putting 10 into x

              x
            +----+
p --------> | 10 |
            +----+

With below

int *q = malloc(sizeof(int));
              y
            +----+
q ------->  |    |
            +----+

You created one more memory y to which q is pointing.

When you assign

q = p;
              x
            +----+
p --------> | 10 |
q --------> +----+

              y
            +----+
Memory leak |    |
            +----+

You made q to point x memory as well, losing the only reference to y memory.

With freeing p

free(p);



p -------->  (invalidated)
q --------> 

              y
            +----+
Memory leak |    |
            +----+

You deleted x memory thus p and q are pointing to freed memory.


Perhaps this would help:

You are not freeing p or q themselves. You are freeing the memory block pointed to by them.

After free(), both p and q themselves continue to exist. You can no longer dereference them, but you can continue using them in other ways. For example, you can make them point to another, valid, address (after which it will again become permissible to dereference them).