Is the Pointer Guaranteed to Preserve Its Value After 'Delete' in C++

Is the pointer guaranteed to preserve its value after `delete` in C++?

No, it's not guaranteed and an implementation may legitimately assign zero to an lvalue operand to delete.

Bjarne Stroustrup had hoped that implementations would choose to do this, but not many do.

http://www.stroustrup.com/bs_faq2.html#delete-zero

Is it good practice to NULL a pointer after deleting it?

Setting a pointer to 0 (which is "null" in standard C++, the NULL define from C is somewhat different) avoids crashes on double deletes.

Consider the following:

Foo* foo = 0; // Sets the pointer to 0 (C++ NULL)
delete foo; // Won't do anything

Whereas:

Foo* foo = new Foo();
delete foo; // Deletes the object
delete foo; // Undefined behavior

In other words, if you don't set deleted pointers to 0, you will get into trouble if you're doing double deletes. An argument against setting pointers to 0 after delete would be that doing so just masks double delete bugs and leaves them unhandled.

It's best to not have double delete bugs, obviously, but depending on ownership semantics and object lifecycles, this can be hard to achieve in practice. I prefer a masked double delete bug over UB.

Finally, a sidenote regarding managing object allocation, I suggest you take a look at std::unique_ptr for strict/singular ownership, std::shared_ptr for shared ownership, or another smart pointer implementation, depending on your needs.

What happens to the pointer itself after delete?

The pointer itself does have an address and the value. The address of the pointer does not change after you perform delete on it. The space allocated to the pointer variable itself remains in place until your program releases it (which it might never do, e.g. when the pointer is in the static storage area). The standard does not say what happens to the value of the pointer; all it says is that you are no longer allowed to use that value until you assign your pointer a valid value. This state of the pointer is called dangling.

In your program, the pointer ptr is dangling after delete has completed, but before the ptr = NULL assignment is performed. After that it becomes a NULL pointer.

The pointer it self is placed on stack or heap?

Pointer variable is a regular variable. Its placement follows the same rules as the placement of other variables, i.e. you can put a pointer in a static area, in an automatic area (commonly known as "the stack") or in the dynamic memory (also known as "the heap"). In this case, you allocate a pointer to a pointer:

TheObject **ptrPtr = new TheObject*; // The pointer to a pointer is on the stack
*ptrPtr = new TheObject; // The pointer to TheObject is in the heap
delete *ptrPtr; // The space for TheObject is released; the space for the pointer to TheObject is not
delete ptrPtr; // Now the space for the pointer to TheObject is released as well
// The space for the pointer to pointer gets released when ptrPtr goes out of scope

The after-effects of deleting a pointer

p is still on the stack and holds the address of the Object you've just deleted. You are free to reuse p, assigning it to point at other allocated data or NULL / nullptr.

Values still accessible after I call delete, c++

If I call delete shouldn't the memory on heap be delete and when print is called not output anything for BankAccount?

No.

Deleting the object at that location in memory means it does not exist any more, so you're not allowed to access it.

It does not mean your program will magically print "nothingness" to protect you from this mistake.

Your program therefore has undefined behaviour; you must make sure you do not dereference an invalid pointer!

c++ delete pointer and then access the value of it points to

You first leaked a pointer

int *p = new int;
p = # // You just leaked the above int

then illegally deleted something you did not new

delete p;  // p points to num, which you did not new

Why should I not try to use this value after delete this?

The reason that you cannot do anything with a pointer after you delete it (this, or any other pointer), is that the hardware could (and some older machines did) trap trying to load an invalid memory address into a register. Even though it may be fine on all modern hardware, the standard says that the only thing that you can do to a invalid pointer (uninitialized or deleted), is to assign to it (either NULL, or from another valid pointer).

Is delete allowed to modify its parameter?

Before the deletion, ptr's value was valid. After the deletion, the value was invalid. Therefore the value changed. Valid values and invalid values are mutually exclusive -- a value cannot be simultaneously valid and invalid.

Your question has a basic misconception; you're conflating these two different concepts:

  • The value of a variable
  • The representation of a variable in memory.

There isn't a one-to-one correspondence between these two things. The same value may have multiple representations, and the same representation may correspond to different values.


I think the gist of your question is: can delete ptr; change the representation of ptr?. To which the answer is "Yes". You could memcpy the deleted pointer into a char array, inspect the bytes, and find them all to be zero-valued bytes (or anything else). This is covered in the standard by C++14 [basic.stc.dynamic.deallocation]/4 (or C++17 [basic.stc]/4):

Any other use of an invalid pointer value has implementation-defined behavior.

It's implementation-defined and the implementation could define that inspecting the bytes gives bytes with value zero.


Your code snippet relies on implementation-defined behaviour. "Valid code" isn't terminology used by the Standard, but the code might not remove the intended item from the hash table.

As alluded to by Stroustrup, this is an intentional design decision. An example usage would be a compiler in debug mode setting deleted pointers to a particular representation, so that it can raise a runtime error if a deleted pointer is subsequently used. Here's an example of that principle in action for uninitialized pointers.

Historical note: In C++11 this case was undefined, rather than implementation-defined. So the behaviour of using a deleted pointer was identical to the behaviour of using an uninitialized pointer. In the C language, freeing memory is defined as putting all pointers to that memory into the same state as an uninitialized pointer has.



Related Topics



Leave a reply



Submit