6
int*a=nullptr; //NULL before C++11
a=new int(1);
delete a;

What does a point to now? Does it point to nullptr or does it point to the address it was pointing to before it was deleted?

Johnathan Gross
  • 678
  • 6
  • 19

4 Answers4

6

A few other answers incorrectly say "the value doesn't change". However it does: before the deletion it was valid, and after the deletion it is invalid; this is a change.

Further, the representation of the value may change too. For example the implementation could set a to be null, or some pattern that the debugger will recognize to help with detecting invalid uses of variables.

M.M
  • 138,810
  • 21
  • 208
  • 365
5

According to the C++ Standard (6.7 Storage duration)

4 When the end of the duration of a region of storage is reached, the values of all pointers representing the address of any part of that region of storage become invalid pointer values (6.9.2). Indirection through an invalid pointer value and passing an invalid pointer value to a deallocation function have undefined behavior. Any other use of an invalid pointer value has implementation-defined behavior.

So after this expression statement

delete a;

the value of the pointer a is not changed but has became invalid. Neither object exists at this address.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • 5
    “the value of the pointer a is not changed”. That’s not what that snippet says. It describes what’s undefined and then states that everything else is *implementation-defined*. That includes reading the pointer’s value. For example it would be perfectly compliant for a compiler to change the value of all deleted pointers to nullptr. – besc Nov 01 '17 at 21:03
  • @besc: are you sure? `nullptr` is not an invalid pointer value. – geza Nov 01 '17 at 21:37
  • @geza nullptr did not point to an object while we are speaking about pointers that pointed to objects. So I do not understand what you mean. – Vlad from Moscow Nov 01 '17 at 21:39
  • @VladfromMoscow: besc said that a compiler could change the pointer value to nullptr. But the standard says that the pointer value becomes invalid pointer value. And a `nullptr` is clearly not an invalid pointer value. – geza Nov 01 '17 at 21:41
  • 1
    What I mean is that you cannot make any assumptions about which value the pointer variable contains after the delete without speaking about a specific (version of a) compiler. The standard says that – excluding the UB cases – any access to that pointer’s value has implementation-defined behaviour. That means the behaviour is entirely up to the compiler vendor, but they must document it. Setting to nullptr was just a quick example of what a vendor could decide. I’m not saying that’s reasonable or even technically possible. I’m just saying the standard explicitly allows things like that. – besc Nov 01 '17 at 21:48
  • @besc, but if the implementation chooses nullptr, then it is not an invalid pointer value. So, in a way, it violates the standard, which says that the pointer value becomes an invalid pointer value. – geza Nov 01 '17 at 21:56
  • @geza I’d have to read the standard in a bit more detail to be sure. How I understand “invalid pointer value” is that this pointer does not point to a valid object anymore, not that the value stored in the pointer variable itself becomes invalid somehow. Provided nobody changed it, essentially it’s still just an integer number that represents a memory address. – besc Nov 01 '17 at 21:58
  • @besc: maybe :) I'm not nitpicking. I've asked a similar question before (check the comments I've made at the question), and unfortunately, it seems that a clear answer cannot be derived from the standard. – geza Nov 01 '17 at 22:08
  • @besc - When we delete a large memory object, the memory manager might return it to the operating system which unmaps the address range. If so, the "integer number" no longer represents a memory address. On some hardware, loading an unmapped value into an address register will trap. – Bo Persson Nov 01 '17 at 23:00
  • @BoPersson: which CPU works like this? Does it have a C++11 compiler? I ask this because of my [question](https://stackoverflow.com/questions/45119928/c11-on-exotic-hardware). – geza Nov 01 '17 at 23:14
  • @geza - I was thinking of the 68000 with dedicated address registers, and the segment registers present in 32-bit x86 (both of which you already have in an answer). It is "just" that nobody cared to support far pointers in a 32-bit OS, but the hardware is still there. Can a language standard forbid the use of those features? – Bo Persson Nov 01 '17 at 23:24
  • @BoPersson, why not, if they don't add anything useful. As I see, we are fine without segment register support (we needed them in the 16-bit era, but currently they're not very useful in a 32/64-bit C++ program). And maybe there is no C++11 compiler for 68000 or with segment register support at all. Thanks for the info on 68000 (I didn't programmed it). – geza Nov 01 '17 at 23:33
  • 1
    For practical purposes I think it’s safe to say that after the object behind a pointer is deleted there are only two sensible things to do with that pointer variable. Re-assign it or let it go out of scope and be cleaned up. If you do anything else, you shall burn in code review! ;) From the language-lawyer perspective I don’t see the ambiguity. To do anything with the “invalid pointer value” there is no way around reading it, which falls under “any other use” and is implementation-defined. – besc Nov 02 '17 at 11:43
4

It doesn't point to anything. There is nothing useful you can do with its value now.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278
4

Don't confuse the pointer's value with what it points to. After the delete, the pointer's value is unchanged. It isn't set to nullptr or anything like that. The thing it points to is undefined. All to often, it ends up pointing to exactly what it did before, which leads to all manner of interesting bugs.

Peter Ruderman
  • 12,241
  • 1
  • 36
  • 58
  • Actually does language specify if value is changed or not? There is no way to check if it changed – Slava Nov 01 '17 at 19:42
  • 1
    *"After the delete, the pointer's value is unchanged."* That's not guaranteed. – Baum mit Augen Nov 01 '17 at 19:43
  • 1
    @BaummitAugen: Would you agree that all of the following guarantee the pointer `a`'s value is unchanged? `delete +a;` `delete a+0;` `delete ((int*)a);` `auto c = a; delete c;` – Ben Voigt Nov 01 '17 at 19:46
  • afaik implementations are allow to set the pointer to `nullptr` during `delete`, – 463035818_is_not_an_ai Nov 01 '17 at 19:47
  • @tobi303: the argument to delete may be a rvalue expression, so it might not be modifieable at all – Andreas H. Nov 01 '17 at 19:48
  • 1
    @tobi303: It is certainly difficult to detect whether it has changed, without introducing undefined behavior. I believe however that one could safely `memcpy` the pointer value (not dereferenced!) to a byte buffer of sufficient size. – Ben Voigt Nov 01 '17 at 19:49
  • @BenVoigt I think so, but how would you check that? Copy its object representation to a `char[]` and compare that? – Baum mit Augen Nov 01 '17 at 19:49
  • @AndreasH. It is possible that the value does not change, but this answer states something different: "After the delete, the pointer's value is unchanged" which is: it cannot change – 463035818_is_not_an_ai Nov 01 '17 at 19:50
  • @BaummitAugen: Yes, that's the only legal operation I can think of, on a pointer holding an invalid value. – Ben Voigt Nov 01 '17 at 19:50
  • @BenVoigt I have to admit that I am a little bit confused after reading [this answer](https://stackoverflow.com/a/44182938/4117728). I am starting to believe that there a millions of programs with UB out there and I am just happy that I didnt use any `delete` since ages – 463035818_is_not_an_ai Nov 01 '17 at 19:53
  • @tobi303 I'm certain that there are millions of programs with UB out there. – François Andrieux Nov 01 '17 at 19:58
  • @Slava: actually, there may be a way. As far as I know, it depends on how one interprets the standard. You're maybe able to check the change with `memcpy`. https://stackoverflow.com/questions/45149756/is-delete-allowed-to-modify-its-parameter – geza Nov 01 '17 at 23:18