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.
Test.exe中0x5ddccaf7(msvcr100d.dll)的未处理异常:0xC00000FD:堆栈溢出。
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.
我知道,将指定的内存处理程序保存在指针以外的其他内容并且*(new ...)很糟糕是没有用的,但我只是想知道,为什么新的工作正常,但删除失败。
//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)
是因为执行程序的模块(它可能不是“编译器”,因为已经有运行时间),当它遇到删除时,它会搜索一些信息,比如指向&i的数据长度(在这些信息的某些内部数组中)所有指针)并没有找到它或解释一些垃圾数据作为此信息? (我想,指针和引用都有,但变量没有)
3 个解决方案
#1
8
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.
您的原始版本不会将i分配给地址。它在堆上分配一个新的int并将其值初始化为5,然后将该值复制到堆栈中的i。您分配的内存(new'ed)无法访问并被泄露。
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.
参考版本有效,因为我指的是其他匿名的新内存。因此&i给出了堆地址。在你的第一个版本中,&i给出了堆栈变量的地址,而不是堆内存,删除堆栈内存是坏消息。
#2
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.
您会收到运行时错误,因为i的地址与operator new返回的地址不同。取消引用new的结果后,您可以复制该值。然后将该副本放入变量i中,变量i具有自动存储中的地址,如果不触发未定义的行为,则无法合法地传递该地址。
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.
但是,当您创建引用时,不进行复制:new的结果通过类型为“reference to int”的变量i引用。因此,引用具有与operator new返回的相同的地址,因此使用该引用的代码工作正常。
#3
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.
i的地址(您要删除的地址)不是分配的内存的地址。
In mathematical notation, &x == &y
implies x == y
, but x == y
does not imply &x == &y
.
在数学符号中,&x ==&y表示x == y,但x == ydoes并不意味着&x ==&y。
#1
8
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.
您的原始版本不会将i分配给地址。它在堆上分配一个新的int并将其值初始化为5,然后将该值复制到堆栈中的i。您分配的内存(new'ed)无法访问并被泄露。
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.
参考版本有效,因为我指的是其他匿名的新内存。因此&i给出了堆地址。在你的第一个版本中,&i给出了堆栈变量的地址,而不是堆内存,删除堆栈内存是坏消息。
#2
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.
您会收到运行时错误,因为i的地址与operator new返回的地址不同。取消引用new的结果后,您可以复制该值。然后将该副本放入变量i中,变量i具有自动存储中的地址,如果不触发未定义的行为,则无法合法地传递该地址。
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.
但是,当您创建引用时,不进行复制:new的结果通过类型为“reference to int”的变量i引用。因此,引用具有与operator new返回的相同的地址,因此使用该引用的代码工作正常。
#3
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.
i的地址(您要删除的地址)不是分配的内存的地址。
In mathematical notation, &x == &y
implies x == y
, but x == y
does not imply &x == &y
.
在数学符号中,&x ==&y表示x == y,但x == ydoes并不意味着&x ==&y。