Наиболее распространенный способ заключается в том, что некоторая информация сохраняется непосредственно перед адресом, который она вам возвращает. Поэтому, если malloc возвращает адрес 0x1004, внутри malloc отложит память, начатую с 0x0FFC, и сохранит различную информацию, такую как размер где-то в памяти между 0xFFC - 0x1003, но приложению будет сказано, что выделение начинается с 0x1004.
Единственное, что имеет значение для освобождения, - это получение того же адреса, который вернул malloc.