2

I've heard much about the C++ delete operator and also have used it a lot so far but I don't know what its real work is exactly.
What I have seen on the web have been the talks on "Deallocating storage space" about it, but it does not make sense well to me for understanding the issue completely.

Please have a look at the snippet of code below.

int main()
{
   int* p = new int(6);
   cout << *p << endl;
   delete p;
}

The pointer p has its own address, since it's a variable (#1). The pointer p, too, has an address inside itself because it's a pointer(#2). The object (unnamed), contains the value 6 inside its memory block, and the address of that memory block is the same as the address of #2. (Because the pointer points to that object using that address.)

Now, what will happen to the addresses #1 and #2 after executing delete;?
What does the C++ language say about this?
And what can be the effect of various compilers on the case?

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
Franky
  • 1,181
  • 2
  • 11
  • 33
  • 1
    That's a `delete` **expression**, not a call of the `delete` **operator**. The latter is a deallocation function that's usually called by a `delete` expression. After the `delete` expression calls an object destructor (or for an array, a sequence of such). – Cheers and hth. - Alf Feb 20 '16 at 16:35

4 Answers4

3
int main() {
    int* p;             // p is at address #1 and the value uninitialized. p will
                        // be at address #1 throughout the whole program.
                        // It is only the value of p that can change.

    p = new int(6);     // The value of p is set to address #2 and your
                        // program now has ownership of sizeof(int) bytes
                        // starting from address #2. The int at address #2
                        // is initialized with the value 6.
    cout << *p << endl;

    delete p;           // Your program releases ownership of the memory at
                        // address #2 and you are not allowed to use it anymore.
                        // The value of p is undefined.

    return 0;
}
Support Ukraine
  • 42,271
  • 4
  • 38
  • 63
  • Not correct about the value of `p` being undefined after `delete`, and totally illegible when presented as comments in code. – user207421 Feb 21 '16 at 01:23
  • 1
    @EPJ - From these links, e.g. http://stackoverflow.com/questions/5002055/is-the-pointer-guaranteed-to-preserve-its-value-after-delete-in-c and http://stackoverflow.com/questions/704466/why-doesnt-delete-set-the-pointer-to-null, it was my understanding that the value of `p` is undefined after delete. Do you have other sources? – Support Ukraine Feb 21 '16 at 05:56
3

Now, what will happen over the address #1, #2 after executing delete; (in the code) please?

The pointer p will have an undefined value, but it'll keep its address ("#1").

The int object at *p (with address "#2") no longer exists. That address now describes memory that is free for use in future allocations.


What does the C++ language say about this?

This:

[C++14: 5.3.5/1]: The delete-expression operator destroys a most derived object (1.8) or array created by a new-expression. [..]

[C++14: 5.3.5/7]: If the value of the operand of the delete-expression is not a null pointer value, then:

  • If the allocation call for the new-expression for the object to be deleted was not omitted (5.3.4), the delete-expression shall call a deallocation function (3.7.4.2). The value returned from the allocation call of the new-expression shall be passed as the first argument to the deallocation function.
  • Otherwise, the delete-expression will not call a deallocation function (3.7.4.2).

And what can be the effect of various compilers on the case?

Provided they are compliant, none. All compilers must behave the same way.

Community
  • 1
  • 1
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • 1
    Are you sure that "The pointer p will remain unaffected"? From other SO answers I have read otherwise, e.g. http://stackoverflow.com/questions/704466/why-doesnt-delete-set-the-pointer-to-null and http://stackoverflow.com/questions/5002055/is-the-pointer-guaranteed-to-preserve-its-value-after-delete-in-c – Support Ukraine Feb 20 '16 at 16:59
  • @4386427: Right good point; I meant that its existence will be unaffected and it won't move anywhere, but since the value can be anything that was misleading. – Lightness Races in Orbit Feb 20 '16 at 17:01
  • 1
    @PreferenceBean: Thank you very much for both of your edition and the answer. I understood the subject. (Especially your answer part). But I didn't understand what means "a most derived object" in `[C++14: 5.3.5/1]`. And the part `[C++14: 5.3.5/7]` was somewhat complicated for me :-) – Franky Feb 20 '16 at 18:14
  • 1
    @franky: Yeah standardese takes some getting used to it. For the purposes of this conversation you can just read it as "object". That passage is hedging its bets because things get a little more complicated when inheritance and polymorphism come into it. – Lightness Races in Orbit Feb 20 '16 at 18:17
2

Regarding

The exact operation of the delete operator

Example code in the question:

delete p;

That's a delete expression, not direct a call of the delete operator. The operator is a deallocation function that's usually called by a delete expression, after the delete expression calls an object destructor (or for an array, a sequence of such). Here's what happens:

  1. If p points to an object of class type then its destructor is called to clean up things, e.g. to free resources.

  2. The relevant deallocation function, an operator delete, is called to free the memory. This is usually the global operator delete, but it can be an operator delete defined by the class in question.

Worth noting that for a placement new expression the placement deallocation function is called, with the same allocator arguments, if construction fails during evaluation of that new expression, but a later delete expression only calls the ordinary standard argument operator delete. I do not know the rationale for this. But it has led to some errors, in particular an infamous one in MFC that manifested only in debug builds, where memory was leaked.

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
2

After delete p ,p still has the same address it used to. The object has gone, so it has no address. The bytes it used to occupy may be used for something else or may have been returned to the OS; there's no way you can look at them without invoking undefined behaviour.

The value of p is no longer useful - and you can't do much with p, except assigning a new value to it or let it be destroyed.

That's what the language says, and the compilers implement it.

Lot more details here: http://en.cppreference.com/w/cpp/language/delete

Alan Stokes
  • 18,815
  • 3
  • 45
  • 64
  • 1
    Thank you for your answer. I think that in (my snipped of code) we don't have any leak but we have a dangling pointer (the `p` after deletion). Do you agree? If so, how to save it from being dangled? For example, how to destroy it? – Franky Feb 20 '16 at 18:43
  • 1
    @franky: If you absolutely need to do manual dynamic allocation, use a smart pointer such as `std::unique_ptr` or `std::shared_ptr` to take care of the *lifetime management*. Don't use raw pointers as owners, use them only as simple referers. Do not adopt the misguided practice of nulling raw pointers: it gives a false sense of security and can thwart the efforts of tools to detect things. – Cheers and hth. - Alf Feb 20 '16 at 19:44
  • Thanks, I would just want to be familiar with it. – Franky Feb 20 '16 at 20:30
  • @franky By returning from the function you safely and succinctly destroy `p`. – Alan Stokes Feb 28 '16 at 20:39