24

Possible Duplicate:
C++ delete - It deletes my objects but I can still access the data?
Can a local variable's memory be accessed outside its scope?

I do not understand what delete really does when I want to free memory allocated with new. In C++ Premiere book it is written:

This removes the memory to which ps pointer points; it doesn’t remove the pointer ps itself. You can reuse ps, for example, to point to another new allocation. You should always balance a use of new with a use of delete; otherwise, you can wind up with a memory leak—that is, memory that has been allocated but can no longer be used. If a memory leak grows too large, it can bring a program seeking more memory to a halt.

So as I understand delete must delete the value in the memory to which pinter points. But it doesn't. Here's my experiment:

int * ipt = new int;   // create new pointer-to-int

cout << ipt << endl;   // 0x200102a0, so pointer ipt points to address 0x200102a0
cout << *ipt << endl;  // 0, so the value at that address for now is 0. Ok, nothing was assigned
*ipt = 1000;     // assign a value to that memory address
cout << *pt << endl;   // read the new value, it is 1000, ok
cout << *((int *) 0x200102a0) << endl;   // read exactly from the address, 1000 too

delete ipt;   // now I do delete and then check
cout << ipt << endl;  // 0x200102a0, so still points to 0x200102a0
cout << *ipt << endl;  // 1000, the value there is the same
cout << *((int *) 0x200102a0) << endl;    // 1000, also 1000 is the value

So what does delete really do?

Community
  • 1
  • 1
Green
  • 28,742
  • 61
  • 158
  • 247
  • 8
    Undefined behaviour is what *this* really does. – chris Jul 22 '12 at 18:45
  • 11
    Terrible, terrible working in that book. Removes the memory? What, does it eject your RAM? – harold Jul 22 '12 at 18:46
  • 7
    When you access the pointer after you've done `delete`, you invoke _'undefined behaviour'_ (which is always unconditionally a _Bad Idea™_). Anything can happen, including that you get the results you see. But you can't rely on that happening; the program could crash, or reformat your disk, or anything nasty like that. – Jonathan Leffler Jul 22 '12 at 18:46
  • 4
    [Eric Lippert's "Book in a Hotel Room" answer](http://stackoverflow.com/a/6445794/922184) has an amazing explanation of this for out-of-scope access. It's not exactly the same in this case, but it's very similar. – Mysticial Jul 22 '12 at 18:49
  • @JonathanLeffler using `delete` is always unconditionally a *bad idea™*. –  Jul 22 '12 at 18:50
  • @harold: "Removes" could easily mean "removes from the list of stuff C++ knows about". In that context, it makes more sense than "deallocates" or "frees". And clarifies (at least in my mind) the fact that if you dereference a pointer that's been `delete`d, you're accessing something that no longer technically exists as far as C++ is concerned. – cHao Jul 22 '12 at 18:50
  • @cHao fair enough - terribly taken out of context, in that case :) – harold Jul 22 '12 at 18:52
  • 4
    1. When you delete the file from your computer, do you think that the file's data is gone forever? Of course, no. If you're fast enough to change your mind, you can restore that files with appropriate software because the information did not go anywhere, only the storage space under that information, the HDD memory, was marked as _vacant_. Same with dynamic memory allocation. It would be too expensive for the system to overwrite each newly vacant memory to destroy the data each time dynamic memory is freed (deleted). – Desmond Hume Jul 22 '12 at 18:57
  • 2. Indeed, why would it do that, no ones needs that data anyways after it was deleted, so why bother? But it doesn't make `delete` useless as it tells the system that it can reuse the freed block of memory for something else, for example, for an array your program is going to allocate the next second. – Desmond Hume Jul 22 '12 at 18:58
  • @Radek: `delete` is necessary unless you have GC. Not everything can *or should be* be allocated on the stack. With that said, it's pretty easy to get rid of *most* uses of it, but not all. And in those cases where it can't be gotten rid of, it's a hell of a lot better than the alternative. – cHao Jul 22 '12 at 18:58
  • @cHao No, use [smart pointers](http://stackoverflow.com/questions/395123/raii-and-smart-pointers-in-c). They'll `delete` it for you. –  Jul 22 '12 at 19:00
  • @Radek: You think smart pointers don't `delete`? What, do you think they just *wish* the pointee away? Somewhere, somehow, a `delete` has to be done, or the world falls apart. – cHao Jul 22 '12 at 19:00
  • @cHao they do delete it. My point is that `delete`-ing things *yourself* is too error-prone, and the semantics of raw pointers are rarely clear (are they owning or not?). –  Jul 22 '12 at 19:03
  • @Radek: The semantics of smart pointers can be pretty sketchy too. You stick a "smart" pointer in an object, and that object has a "smart" pointer back to you...congratulations. Circular reference. You just caused a memory leak *while using smart pointers*. – cHao Jul 22 '12 at 19:10
  • @cHao having two objects own each other is a design flaw; it's not specific to C++. One would be a raw, non-owning pointer and the other one would be a `unique_ptr`. –  Jul 22 '12 at 19:12
  • @RadekSlupik: Not to C++...but to any language that does pure reference counting. In languages with built-in GC that's worth a damn, the two objects are not reachable and both get discarded. But anyway, back to C++. Consider a doubly linked list. No node in the list truly "owns" another; they just point at each other. How does that list clean up sans `delete`? – cHao Jul 22 '12 at 19:41

6 Answers6

69

Think of memory as a big warehouse with lots of boxes to put things into. When you call "new", the warehouse staff finds an unused box large enough for your needs, records that box as being owned by you (so it's not given to someone else), and gives you the number of that box so you can put your stuff into it. This number would be the "pointer".

Now, when you "delete" that pointer, the reverse happens: the warehouse staff notes that this particular box is available again. Contrary to real warehouse staff they aren't doing anything with the box — so if you look into it after a "delete" you might see your old stuff. Or you might see somebody else’s stuff, if the box was reassigned in the meantime.

Technically, you are not allowed to look into your box once you have returned it to the pool, but this is a somewhat weird warehouse with no keys or guards, so you can still do whatever you want. However, it might cause problems with the new owner of the box, so it's expected that you follow the rules.

Nathan Tuggy
  • 2,237
  • 27
  • 30
  • 38
Christian Stieber
  • 9,954
  • 24
  • 23
  • *Now, when you "delete" that pointer*... I think you mean when you delete the box associated with your number, not deleting the number directly. Deleting the number would cause a memory leak... – Anonymous Penguin Jan 18 '15 at 04:24
  • Incorrect. It's undefined. How can you possibly see the same memory you *just* freed? This is a good attempt at an answer, though. – Don Larynx Jun 16 '15 at 23:53
  • "_Technically, you are not allowed to look into your box once you have returned it to the pool_" I'm not sure this is 100% correct. See my answer here http://stackoverflow.com/a/42629472/917428 – Ste_95 Mar 08 '17 at 07:49
9

Your experiment has undefined behavior as soon as you dereference the pointer after the delete statement. Everything can happen, which makes your experiment rather worthless.

What does delete (not delete[]) do? It deallocates the storage pointed to by its argument. This will trigger the destructor of the object stored at that location to be run. Accessing storage that has been deleted triggers undefined behavior (often a segmentation fault). There are no guarantees that the memory is actually handed back to the operating system or anything else.

pmr
  • 58,701
  • 10
  • 113
  • 156
6

The delete operator frees the memory which was previously allocated using the new operator. This means that the memory is now available to be used by the system, for instance when there is another use of new later in the program. It does not clear the data in the memory, however. The pointer will still point to the same address in memory, but accessing that block will result in undefined behavior.

It is good practice to set a pointer to NULL (or nullptr in C++11) after deleteing it. Any subsequent deletes will be harmless.

Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268
6

Dereferencing the pointer after delete-ing it is undefined behavior, so anything can happen.

Usually, delete marks the memory as freed so it can be reused later, but this is a complicated topic.

Rule of thumb: never, ever use new and delete directly (except for implementing make_unique, which the standard lacks for some reason); use RAII.

6

delete makes the memory available for later requests via new. Whether or not it scrambles to content is undefined. Since it is faster to leave the contents as they are, in release mode it will probably appear that the memory is still "available". In debug mode, it might get scrambled with magic numbers.

What you're experiencing here is called "undefined behavior" in C++. In this case, the undefined behavior is caused by accessing a piece of memory after its lifetime has ended. Just don't do it.

fredoverflow
  • 256,549
  • 94
  • 388
  • 662
4

delete returns the memory back to the system -- basically, it is no longer reserved for your program anymore. That does not mean that the values in the memory will be immediately overwritten, but the could be at any time after the delete is done. Most of the time, the same memory is reallocated to some future use by your own program.

Turix
  • 4,470
  • 2
  • 19
  • 27