如果我分配了一个int
对象的存储位置动态如下:动态内存分配“删除”
int *x = new int;
完成它后,并要释放堆上的内存,我会做以下内容:
delete x;
现在,如果我没有不做到以下几点:
x = NULL;
将x
指着另一个地址? UPDATE:another
代替many
说我没有做x = NULL
并提出另一delete x;
,会发生什么?
如果我分配了一个int
对象的存储位置动态如下:动态内存分配“删除”
int *x = new int;
完成它后,并要释放堆上的内存,我会做以下内容:
delete x;
现在,如果我没有不做到以下几点:
x = NULL;
将x
指着另一个地址? UPDATE:another
代替many
说我没有做x = NULL
并提出另一delete x;
,会发生什么?
x
(除了= NULL
- 这是,海事组织,是不好的做法)你删除后是不确定的。注意:一些运行时系统会 保护你一定很简单 情况下双删除。根据 的细节,你可能是正确的,如果你 碰巧这些 系统之一,如果没有人部署 您在另一个系统 处理不同的事情,如果你 被删除的东西,没有按”代码运行牛逼 有析构函数,如果你没有做任何事情 两个 删除之间,如果没有人改变 你的代码做两个删除您 线程调度器之间,如果发生显著 (超过您 可能显著没有控制!) 碰巧交换了两个线程之间的线程 d电子邮件,如果,如果,如果,如果。所以 回墨菲:因为它可能会出错, 它会的,它会在最糟糕的时刻出错。
的delete
后,指针通常将仍然包含(现在空闲)存储器的地址。第二个delete
给出未定义的行为,所以不要这样做。
它会调用未定义的行为。如果你不这样做x=NULL
然后x
将指向一个无效的内存位置,如果你尝试使用将导致未定义的行为。
但是,当我做'删除',我不删除'指针'本身?你如何说'如果你不这样做x = NULL那么x将指向一个无效的内存位置'?谢谢 – Simplicity 2011-01-29 14:43:53
@ user588855:可以说在删除之前`x`是0x11111111。所以当你做'删除x'时,这个内存位置是免费的。但是由于您没有将`x`设置为`NULL`,它仍然具有值为'0x11111111`,这是一个释放的内存位置。尝试使用`* x`或`x->`读/写这个位置将会调用未定义的行为。 – Asha 2011-01-29 16:39:13
调用删除已经删除的内存将导致未定义的行为。通常,你的程序会崩溃。
删除x后,它将指向的地方是“依赖于编译器”。在调用删除之前,大多数编译器都会让它指向它的位置。但是该内存地址不再有效,因此不应该被调用。
出于同样的原因,如果需要的话,“删除此”必须非常审慎和谨慎地使用。 :-)
当你说:`调用删除已经删除的内存将导致未定义的行为。它不是被删除的`指针',而不是'内存'?谢谢 – Simplicity 2011-01-29 14:46:02
类型:
int main(){
int* i = new int;
std::cout << i << std::endl;
delete i;
std::cout << i << std::endl;
delete i;
}
结果:
0x8e19008
0x8e19008
** glibc的检测** ./a.out:双游离或腐败(fasttop ):0x08e19008 *
as y ou看到,地址保持不变,但第二次删除以运行时错误结束。行为可能在很大程度上取决于环境,但作为一般规则,这种行为是行不通的。
第二次删除未定义。
作为一个方面说明,有工具来检测双重删除。其中最好的一个是Valgrind。
http://www.parashift.com/c%2B%2B-faq-lite/freestore-mgmt.html#faq-16.2 – 2011-01-29 09:15:26