After delete p, immediately write p = nullptr. This two-line pattern prevents both dangling pointer use and double delete. Dereferencing nullptr crashes immediately with a clear error.
Without this practice, p still holds the old address. Code checking if (p) sees it as valid even though the memory is freed. The check passes but the access fails. Smart pointers do this automatically.
When a unique_ptr goes out of scope, it deletes and nulls itself in one atomic operation. This is one reason to prefer smart pointers.