[Edit: this is an attempt to answer the original poster's question. The question may or may not have been changed by shog9's edit - it's hard to say since the original was unclear...]
If you mean, as others have assumed, setting 0 for every byte of the memory block being freed, then you cannot do that after freeing the block. Attempting to do it yields undefined behaviour. So if you're doing that, then you have badly misunderstood memory allocation.
But I'm guessing when you say "we set it to zero after freeing", you're maybe talking about code like this:
free(ptr);
ptr = NULL;
If so, then the reason free can't set ptr to NULL, is that free only receives the value from the variable ptr. It has no way of modifying ptr, because you aren't passing the variable ptr itself into free. You're just passing the address currently stored in it. This is part of the design of the C language - when you call a function passing a value, then the callee cannot tell how that value was computed, or what variable might contain it in the caller's code. Making an exception to this language rule just for free would be crazy, even if it were possible.
In any case, not everyone zeroes out pointers after freeing them. Some people think it's a good safety measure, other people think it is not. Whatever you think of it, though, the code doesn't zero the memory, it only zeros the pointer to the memory. If you want to write a function which clears the pointer for you, then you can:
void free_and_clear(void **pptr) {
free(*pptr);
*pptr = NULL;
}
Then use it like this:
free_and_clear(&ptr);
Note that this passes a pointer to the variable ptr, instead of the value of ptr. So free_and_clear can modify ptr. But this puts some restrictions on how you can use it which don't apply to free - you need a pointer to a modifiable value, rather than just a value.