Freeing the same block twice is a classic bug that corrupts a real allocator. Ours should refuse it. Today Free checks that the block it is asked to release is actually allocated, and reports an error otherwise.
Reject a free of an already-free block with an error, leaving the heap intact.
A double free - releasing a block that is already free - is one of the most damaging bugs in real programs: it typically inserts the same block into the free list twice, so a later allocation hands the same memory to two owners. Because our allocator records an allocated flag on every block, it can catch this cheaply: if the block at the given offset is already free, refuse.
Return an error and change nothing. The heap stays exactly as it was, and the checker still passes - the whole point is that a misuse is rejected without corrupting anything. This is the first of two guards that turn silent corruption into a clean error; the next handles offsets that were never valid allocations at all.
func (a *Allocator) Free(payload int) error {off := payload - 8size, alloc := a.blockAt(off)if !alloc {return fmt.Errorf("double free at %d", payload)}// ... clear flag, coalesce, insert ...}