p = NULL;
merely sets p
to NULL, but does nothing to the memory that p
was pointing at.
delete p;
frees the memory that p
is pointing at, provided that memory was allocated with new
(as it is in your example).
In your example, trying to access *p
after calling delete p;
is undefined behavior, so anything can happen. p
is still pointing at the same address it was before, delete
does not alter p
itself in any way, but the memory that p
is pointing at is no longer valid. You happen to be seeing the old data that was stored in that memory, but only because it simply hasn't been overwritten yet. But it is still not permissible to access invalid memory for any reason. The actual memory be still be physically allocated by the underlying memory manager, but is logically inaccessible to your code, until it is reallocated again.