0

Walter Savitch's ``Problem Solving With C++, 9th Edition'' states on page 517:

When you apply delete to a pointer variable, the dynamic variable it is pointing to is destroyed. At that point, the value of the pointer variable is undefined, which means that you do not know where it is pointing, nor what the value is where it is pointing. Moreover, if some other pointer variable was pointing to the dynamic variable that was destroyed, then this other pointer variable is also undefined.

However, it seems that under clang-902.0.39.1, deleting a pointer doesn't impede my ability to use the variable. Here is a short example demonstrating this behavior:

int *p1, *p2;
p1 = new int(3);
p2 = p1;

cout << *p1 << endl << *p2 << endl;

delete p1;

cout << *p1 << endl << *p2 << endl;

Using this code, I have an output of 4 3s on separate lines. I would expect an error to occur when referencing p1 and p2 after delete p1;, should I not?

Under Visual Studio's C++ compiler, referencing p2 outputs a large negative number, indicating we are referencing memory that does not belong to us, and accessing p1 causes the program to crash.

Ivan G.
  • 700
  • 8
  • 19
  • 6
    "I would expect an error to occur" undefined behavior != throws an error. – tkausl Apr 24 '18 at 18:13
  • Looks pretty undefined indeed. – bipll Apr 24 '18 at 18:15
  • 3
    The most insidious part of undefined is it could look like it works right up until it suddenly doesn't. – user4581301 Apr 24 '18 at 18:27
  • 2
    If you have some time to kill and really want to learn this, check out [valgrid](https://www.cprogramming.com/debugging/valgrind.html). Running your program under it will reveal the memory violations. – JimPri Apr 24 '18 at 18:30
  • 1
    "Undefined behavior" is quite literally undefined. It *can* produce an error message, or it can "work anyway", or it can set your laundry on fire while playing "Happy Birthday" through the speakers. All of these options are standards-compliant. – Jesin Apr 24 '18 at 18:31
  • A deleted value doesn't have to go away *immediately*. To help you remember this, please also see https://stackoverflow.com/a/6445794/597607 – Bo Persson Apr 24 '18 at 18:59
  • Possible duplicate of https://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope – linuxfever Apr 24 '18 at 20:53
  • Please be aware that the author uses non-standard terminology. "Dynamic variable" apparently refers to "an object created by `new`". In standard C++ terminology, such an object is _not_ a variable and does _not_ have a name. – MSalters Apr 25 '18 at 09:52

4 Answers4

4

I would expect an error to occur when referencing p1 and p2 after delete p1;, should I not?

Not necessarily.

At that point, the value of the pointer variable is undefined

Undefined, as in, to use the pointer after delete has been called on it may cause anything to happen, good, bad, or neutral.

The compiler is not required to put up any runtime barriers to further use of the pointer. In particular, it's not required to end the program immediately. Of course, a good compiler (with the right settings) might warn you if it sees your code reusing deleted pointers.

Under Visual Studio's C++ compiler, referencing p2 outputs a large negative number, indicating we are referencing memory that does not belong to us, and accessing p1 causes the program to crash.

A particular compiler may create a process which, on a particular operating system, under particular memory load conditions, causes a crash. Or it may not. Similarly, there is no requirement that the memory associated with the pointer be filled with garbage data.

In particular, I believe that Visual Studio in a debug build may instrument the pointer's memory so that further use results in a crash/exception. This is useful for debuggability.

Aside from debug builds, the only problems that can result are incidental. Consider the following possibilities for a pointer which has delete called and is then reused:

  • The process has released the memory to the operating system. Your program is now attempting to access memory it has no rights to. SEGFAULT (crash).
  • Internally, the memory has been marked as belonging to a different variable (i.e. some other part of your program called new or similar), and has been written to. It may appear to be filled with garbage data. There may or may not be an issue depending on how your program uses the variable. It may crash, it might print out garbled text, etc.
  • Internally, the memory is marked as deleted, but no other part of your program required it. The memory is left untouched, for the moment. This is what you saw under clang, presumably.

In short, while predicting what will happen to the memory for a deleted pointer is tricky, the only responsibility given to the programmer is this: To not use it again.

iPherian
  • 908
  • 15
  • 38
1

That memory is still there when you delete the pointer and the pointer still points to it. However, you have no guarantees that it will still be valid or that it will still exist in the future. The memory allocation (new/malloc/etc) has marked that location in memory as no longer used, so it may reallocate it or release all of the memory on the page(s), at which point accessing it will result in an access violation (segfault).

For instance, if I create three new ints using pointers, they will likely be placed next to each other in memory. If I delete the middle pointer, the address of it is still valid since the page of memory cannot be freed until all of the memory for it is no longer valid. However, even though I can access the memory for the now deleted pointer, I shouldn't. That's because if I create a new int pointer, it will likely be assigned to that new spot.

BAD METAPHOR: Memory is like seats in a classroom. Some people need more seats (or put their feet up or place their bag) and some people need less. You cannot remove a classroom from a school until all seats in that classroom are free. If you ask to be assigned a seat, you may get room1, seat2. If you give up that seat (like deleting a pointer), you can still refer to room1/seat2, even though it is not yours anymore. If you try to sit in it, you may find that someone else has already been assigned it. If you do sit in it, the classroom may be closed at anytime because you said you were done with your seat.

seat = memory that your pointer points to

classroom = page of memory

JimPri
  • 1,278
  • 8
  • 17
0

Your pointers are still pointing to old position, just this memory doesn't belong them anymore. Later there could be another data. So it's not stable output.

Alexey Usachov
  • 1,364
  • 2
  • 8
  • 15
0

The memory has been released, but your pointers are still pointing to where the data used to be.

MarkInTheDark
  • 244
  • 2
  • 15