2011-01-29 77 views
1

如果我分配了一个int对象的存储位置动态如下:动态内存分配“删除”

int *x = new int;

完成它后,并要释放堆上的内存,我会做以下内容:

delete x;

现在,如果我没有做到以下几点:

x = NULL;

x指着另一个地址? UPDATE:another代替many

说我没有做x = NULL并提出另一delete x;,会发生什么?

+1

http://www.parashift.com/c%2B%2B-faq-lite/freestore-mgmt.html#faq-16.2 – 2011-01-29 09:15:26

回答

6
  1. 任何你与x(除了= NULL - 这是,海事组织,是不好的做法)你删除后是不确定的。
  2. double-delete =灾难。

注意:一些运行时系统会 保护你一定很简单 情况下双删除。根据 的细节,你可能是正确的,如果你 碰巧这些 系统之一,如果没有人部署 您在另一个系统 处理不同的事情,如果你 被删除的东西,没有按”代码运行牛逼 有析构函数,如果你没有做任何事情 两个 删除之间,如果没有人改变 你的代码做两个删除您 线程调度器之间,如果发生显著 (超过您 可能显著没有控制!) 碰巧交换了两个线程之间的线程 d电子邮件,如果,如果,如果,如果。所以 回墨菲:因为它可能会出错, 它会的,它会在最糟糕的时刻出错。

https://isocpp.org/wiki/faq/freestore-mgmt

5

delete后,指针通常将仍然包含(现在空闲)存储器的地址。第二个delete给出未定义的行为,所以不要这样做。

2

它会调用未定义的行为。如果你不这样做x=NULL然后x将指向一个无效的内存位置,如果你尝试使用将导致未定义的行为。

+0

但是,当我做'删除',我不删除'指针'本身?你如何说'如果你不这样做x = NULL那么x将指向一个无效的内存位置'?谢谢 – Simplicity 2011-01-29 14:43:53

+0

@ user588855:可以说在删除之前`x`是0x11111111。所以当你做'删除x'时,这个内存位置是免费的。但是由于您没有将`x`设置为`NULL`,它仍然具有值为'0x11111111`,这是一个释放的内存位置。尝试使用`* x`或`x->`读/写这个位置将会调用未定义的行为。 – Asha 2011-01-29 16:39:13

1

调用删除已经删除的内存将导致未定义的行为。通常,你的程序会崩溃。

删除x后,它将指向的地方是“依赖于编译器”。在调用删除之前,大多数编译器都会让它指向它的位置。但是该内存地址不再有效,因此不应该被调用。

出于同样的原因,如果需要的话,“删除此”必须非常审慎和谨慎地使用。 :-)

+0

当你说:`调用删除已经删除的内存将导致未定义的行为。它不是被删除的`指针',而不是'内存'?谢谢 – Simplicity 2011-01-29 14:46:02

2

类型:

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看到,地址保持不变,但第二次删除以运行时错误结束。行为可能在很大程度上取决于环境,但作为一般规则,这种行为是行不通的。

1

第二次删除未定义。

作为一个方面说明,有工具来检测双重删除。其中最好的一个是Valgrind