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
C++ Compiler Error C2280 "Attempting to Reference a Deleted Function" in Visual Studio 2013 and 2015
Taking the Address of a Temporary Object
Practical Use of Zero-Length Bitfields
Is It Legal to Redefine a C++ Keyword
Std::Vector, Thread-Safety, Multi-Threading
Why Does Std::Cout Convert Volatile Pointers to Bool
Why Doesn't Narrowing Conversion Used with Curly-Brace-Delimited Initializer Cause an Error
How to Find the Actual Path Found by Bfs
Random Array Generation with No Duplicates
"The System Cannot Find the File Specified" When Running C++ Program
How to Use Polymorphic Attributes with Boost::Spirit::Qi Parsers
C++17 Class Template Partial Deduction