You can use the pointer as an object id, but only for living objects.
The pointer becomes invalid the moment the memory is freed. Your bug
was that you used an invalid pointer.
Exactly, but just declaring that a pointer is "invalid" doesn't help much with debugging such dangling pointer problems, while tagged pointers do.
It's not like an "invalid pointer" is any different from a "valid pointer" when you look at it. With the extra tag bits, an invalid pointer can actually be identified as such.