1

如果我为对象动态分配内存位置,int如下所示:

int *x = new int;

完成后,想要释放堆上的内存,我将执行以下操作:

delete x;

现在,如果我没有执行以下操作:

x = NULL;

x指向另一个地址吗?更新: another而不是many

说我没有做x = NULL,又做了一个 delete x;,会发生什么?

4

6 回答 6

6
  1. 删除后您所做的任何事情x(除了= NULL- 即 imo,不好的做法)都是未定义的。
  2. 双重删除=灾难。

注意:一些运行时系统会保护您免受某些非常简单的双重删除情况的影响。根据详细信息,如果您碰巧在其中一个系统上运行,并且如果没有人将您的代码部署在另一个处理方式不同的系统上,并且如果您要删除没有析构函数的东西,并且如果您在两次删除之间没有做任何重要的事情,并且如果没有人更改您的代码以在两次删除之间做一些重要的事情,并且您的线程调度程序(您可能无法控制!)不会碰巧在之间交换线程这两个删除了and if,and if,and if。所以回到墨菲:既然它可能出错,它就会出错,而且它会在最糟糕的时刻出错。

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

于 2011-01-29T09:12:05.253 回答
5

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

于 2011-01-29T09:12:13.630 回答
2

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

于 2011-01-29T09:13:07.913 回答
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 *

如您所见,地址保持不变,但第二次删除以运行时错误结束。行为可能在细节上取决于环境,但作为一般规则,它不会起作用。

于 2011-01-29T09:15:53.597 回答
1

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

删除 x 后,它将指向的位置是“编译器相关”。在调用 delete 之前,大多数编译器只会让它指向它所在的位置。但是那个内存地址不再有效,因此不应该被调用。

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

于 2011-01-29T09:13:18.897 回答
1

第二次删除未定义。

作为旁注,有一些工具可以检测双重删除。周围最好的之一是Valgrind

于 2011-01-29T09:37:18.157 回答