How malloc and free work is implementation defined. Commonly the info about the memory block would be stored in a header just below ptr. But not necessarily.
The great thing about malloc and free is that you don't need to know how they work. The system takes care of the details for you.
I read somewhere that calling free twice using the same pointer argument causes undefined behavior. In order to understand this I must first know how free works?
I'm not sure I agree with this statement. You simply need to follow the rule.
Does the heap always allocate contiguous memory when we call malloc/calloc/realloc?
If you mean that the block of memory returned is contiguous in the address space, then yes that is so. If you mean that successive allocations are sequential, then no.