My C is quite rusty, so apologies for stupid questions.
In the hm_put function, when you overwrite, why do you malloc and copy the key again, and what happens with the old key pointer and the old value pointer? (no free for the key and the memset zeros everything?)
Nice catch :)
Looks like the key logic is missing an overwrite case, the value is reallocated on overwrite.