-2

My question is exactly analog to this one:
Is the compiler allowed to recycle freed pointer variables?
but in the case of C++.

In the case of C, ISO/IEC 9899:1999 §6.2.4, paragraph 2 says:

The lifetime of an object is the portion of program execution during which storage is guaranteed to be reserved for it. An object exists, has a constant address, and retains its last-stored value throughout its lifetime. If an object is referred to outside of its lifetime, the behavior is undefined. The value of a pointer becomes indeterminate when the object it points to reaches the end of its lifetime

However, looking at the latest C++ standard, I could not find any definitive answer to that question.

My understanding at the moment is that in C++, while the memory location pointed to by a pointer that has been deleted is indeed invalid, the value of the pointer itself is not allowed to change, unless the programmer instructs the program to do so.

Could anybody point me to some reference material that could bring a definite answer to this question?

Student
  • 805
  • 1
  • 8
  • 11
Tachikoma
  • 179
  • 2
  • 9
  • The "value of the pointer" is just a number. A memory address. Of course the address can be re-used. – Jesper Juhl Jul 28 '18 at 13:44
  • 1
    The pointer variable holds the address and as you said it doesn't change once the object is deleted, so the compiler cannot "recycle" it. However the memory pointed to will likely be "recycled" depending on the memory allocator (but the compiler has nothing to do with this) – Olivier Sohn Jul 28 '18 at 13:46
  • Actually you're right. I actually missed that thread when posting this question. – Tachikoma Jul 28 '18 at 14:54
  • @OlivierSohn Incorrect; after an object is deleted all pointers to it become invalid – M.M Jul 29 '18 at 01:26
  • @M.M The value of the pointer variable holding the memory address to the object doesn't change after the object is deleted. It now points to an invalid object which has been deleted, sure, but it points to the same memory location as before. So you're wrong in saying my comment is incorrect :) – Olivier Sohn Jul 29 '18 at 07:26
  • @OlivierSohn The value of the pointer does change, and it does not point to the same memory location as before. See the linked question for further explanation – M.M Jul 29 '18 at 07:29
  • @M.M Oh ok, but I don't know any implementation that does this, all implementations I've used behave the way I described. – Olivier Sohn Jul 29 '18 at 07:40

1 Answers1

1

If we have:

int * a = new int;
int * b = a;
delete a;
std::cout<< (a==b) << "\n";

the standard does not state the answer is true.

The value of both a and b is indeterminate once the object *a ends its lifetime.

Most physical hardware implementations of pointers are not going to care, but the C++ language is defined in terms of not what physical hardware does, but rather an abstract machine. And in the abstract machine, the values of a and b are indeterminate.

Compilers are free to track all pointers to objects and null them the moment the objects ends its lifetime. Any program relying on the value of a pointer to an object beyond its lifetime is, at the least, fragile.

And as trap values of pointers are permitted by C++, the a==b comparison may permit UB (I am not certain, I am just raising the risk).

Even outside of this, compilers can optimize based on the abstract machine. For example, if we have int* guard=new int;, and we then compare pointers against guard, once the compiler proves guard is deleted it can proceed to assume all branches where you compare pointers to guard are either not reached (if UB is permitted; I am unsure) or return an arbitrary true/false value.

That kind of optimization happens "in the wild" already; I am uncertain it happens with pointers to objects whose lifetime ended. But the next point release of your compiler could start doing it.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
  • 2
    A use of an invalid pointer value that does not indirect through it or attempt to deallocate it (again?), particularly an lvalue-to-rvalue conversion, is implementation-defined behavior. [basic.stc]/4, [conv.lval]/(3.3). So it might be as bad as UB, but they would have to tell us so. – aschepler Jul 28 '18 at 15:01
  • 1
    In C++, deleted pointers take on *invalid pointer value*, not *indeterminate value*. (C++17 [basic.stc]/4). The comparison causes implementation-defined behaviour, not UB (ibid.) – M.M Jul 29 '18 at 01:30