// lesson: deleting-entries

Deleting Entries

Removing from a singly linked chain has a classic wrinkle: unlinking a node means updating whatever pointed to it โ€” the bucket head for the first node, the previous node's next for the others. Handling those as two cases works but doubles the code and the bugs.

The idiomatic C fix is a pointer to a pointer. Instead of walking entries, walk the links:

struct hm_entry **pp = &m->buckets[index];
while (*pp && strcmp((*pp)->key, key) != 0)
	pp = &(*pp)->next;

Now pp points at either the bucket head or someone's next field โ€” it doesn't matter which. Unlinking is uniform: save *pp, redirect *pp to the doomed node's next, free the node. One code path, no special cases.

pp holds the address of a link (the bucket head or some node's next field), and *pp is the node that link points to โ€” the one to remove. The solid arrow is *pp now; the dashed arrow is where *pp points after *pp = (*pp)->next swings the link past the doomed node:

ppfrontkey"front"next"middle""back" *pp *pp = (*pp)->next
ppfrontkey"front"next"middle""back" *pp *pp = (*pp)->next

And because the map allocated the key copy and the node in hm_put, the map must free them here โ€” every malloc needs exactly one free, and the grader's tests will exercise remove-then-lookup to make sure the entry is truly gone, not just leaked.

โ€บ Remove

10 pts

Implement hm_remove with the pointer-to-pointer walk. Free both the key copy and the node; return 1 if a key was removed, 0 if it wasn't there.

Log in to submit a solution and earn points.