Calling delete on address of variable
Asked Answered
B

3

5

Why can I do:

int i = *(new int (5));

and successfuly use i after it,

but when I'm trying:

delete &i;

I get a run time error:

Unhandled exception at 0x5ddccaf7 (msvcr100d.dll) in Test.exe: 0xC00000FD: Stack overflow.

If i was a reference:

int & i = *(new int (5));

, all this (including delete) works fine.

I know, that it's no good to keep allocated memory handler in something other than pointer and *(new ...) is awful, but I'm just wondering, why new works good, but delete fails.

//Below are just my guesses about the reason of such behavior:

Is it because module which executes program (it's probably not "compiler", because of there is run time already) when it encounters with delete, it searches for some information like length of data pointing by &i (in some internal array of such information about all pointers) and don't find it or interpretes some trash data as this information? (I suppose, pointers and references have it, but variables don't)

Blindage answered 22/12, 2014 at 18:10 Comment(9)
Pointers and references are not the same. You cannot delete a reference.Foxglove
You understand int i = *(new int (5)); is an instant-memory-leak, right?Earthen
Because when you do int i = *(new int (5));, the original pointer to *(new int(5)) is lost and i is initialized to the value of this expression, which is 5. i and new int(5) are not the same locations, though, which is why you can't delete &i.Ambie
@Ben, I suppose, for references works delete &i; (not deleting reference, but the data, it's points to) At least, I haven't errors on this line.Blindage
@user3241228 that line is valid. You cannot delete a reference. You can delete something referenced if it was dynamically allocated, which is what your second example does. And though it is rarely done, it is perfectly legal to do so. Do not think of it as deleting a reference; remember address-of applied to a reference returns the address of the referenced (the "ed" in that word is important).Earthen
@WhozCraig, to be honest, I didn't, until the Daniel Kamil Kozar's comment (Thanks, Daniel)Blindage
@Ben you can delete the address of a reference. (Whether this is UB or not depends on what the reference was bound to)Maeda
@MattMcNabb, can you give a couple of examples when it causes UB and when doesn't? Thank you.Blindage
@user3241228 delete can only be called on the same pointer as was new'd , or that pointer converted to a base class which has virtual destructor. Other cases are UB.Maeda
B
9

Your original version does not assign i to an address. It allocates a new int on the heap and initializes its value to 5, then copies that value into i which is on the stack. The memory that you allocated (new'ed) is inaccessible and gets leaked.

The reference version works because i refers to the otherwise-anonymous new'ed memory. Hence &i gives the heap address. In your first version, &i gives the address of the stack variable, not the heap memory, and deleting stack memory is bad news.

Bedder answered 22/12, 2014 at 18:13 Comment(0)
T
4

You get a run-time error because the address of i is not the same as the address returned by the operator new. Once you dereference the result of new, you make a copy of the value. That copy is then placed into variable i, which has an address in automatic storage, which cannot be passed to delete legally without triggering undefined behavior.

When you make a reference, however, you do not make a copy: the result of new becomes referenced through a variable i of type "reference to int". Hence, the reference has the same address as has been returned by operator new, so the code that uses the reference works fine.

Tobiastobie answered 22/12, 2014 at 18:13 Comment(0)
A
4

The line:

int i = *(new int (5));

Is equivalent to:

int* p = new int(5);
int i = *p;

The address of i (which you are trying to delete) is not the address of the allocated memory.

In mathematical notation, &x == &y implies x == y, but x == ydoes not imply &x == &y.

Alberic answered 22/12, 2014 at 18:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.