In StackAllocator you're doing this:
AllocationHeader allocationHeader{padding}; AllocationHeader * headerPtr = (AllocationHeader*) headerAddress; headerPtr = &allocationHeader;
Which doesn't copy the AllocationHeader object that's created on the stack into the memory position.
You should either use
memcpy(headerAddress, &allocationHeader, sizeof(AllocationHeader))
or just use placement new operator to create the object at the memory location.
I've tested this and just as I expected, you're actually getting garbage when you're reading the header in the Free function.