Does the free function make a pointer NULL in C?

No, it doesn’t.

The free library function places the specified block of memory back onto the heap’s free list (at least conceptually…actual implementation details can vary). But the free function doesn’t have access to the memory containing the pointer, because it operates on a copy of the pointer. So, it has no way of changing the value of the pointer (i.e., it can’t change where the pointer points). Thus, after calling free, the contents of your pointer hasn’t changed. It now points to a block of memory that you no longer own.

To avoid reusing the pointer to a block that has already been freed, it’s a good practice to set it to NULL immediately after freeing it.

p = NULL;

That way, if you do have a bug that happens to attempt to use the pointer after the memory block has been freed, you’ll get (in many environments) a nice segfault or access violation, rather than end up with a corrupted heap. The latter can be much more difficult to track down. Avoid corrupting the heap.

Another approach involves placing a wrapper function around free, and using that instead of free. The wrapper can guarantee that the pointer will be set to NULL after the block is returned to the heap.

void superFree(void **pptr)
    // If the address of the pointer is NULL or
    // the pointer itself is already NULL, do
    // nothing.
    if (pptr && *pptr)
        *pptr = NULL;
// ...
// Then, when we want to free a block of allocated memory,
// pointed to by the p pointer variable, we can say:

By providing our function with the address of the pointer, we give the function the power to change where the pointer points, setting it to NULL in this case.

Now, none of this helps at all if you have another copy of the pointer lying around in some other variable or data structure. But if you have only one copy of the pointer to a block of allocated memory, ensuring that it’s set to NULL after the block is freed is a good habit.