如果我动态地为int
对象分配了一个内存位置,如下所示:
int *x = new int;
完成它之后,想要释放堆上的内存,我将执行以下操作:
delete x;
现在,如果我不,请执行以下操作:
x = NULL;
x
会指向另一个地址吗? 更新: another
代替many
说我没有x = NULL
并且另一个 delete x;
,会发生什么?
答案 0 :(得分:6)
x
进行的任何操作(除了= NULL
- 即imo,不良做法)都是未定义的。注意:某些运行时系统会 保护你免受某些非常简单 双删除的情况。取决于 细节,你可能没问题 恰好在其中一个上运行 系统,如果没有人部署 你的代码在另一个系统上 以不同方式处理事情,如果你 正在删除没有的东西 有一个析构函数,如果你不这样做 两者之间有什么重要的 删除,如果没有人改变 你的代码做一些重要的事情 在两个删除之间,如果你的 线程调度程序(在其上 可能无法控制!)没有 碰巧在两者之间交换线程 删除以及if,if和if。所以 回到墨菲:因为它可能出错, 它会,而且它会出错 最糟糕的时刻。
答案 1 :(得分:5)
在delete
之后,指针通常仍然包含(现在空闲)内存的地址。第二个delete
给出了未定义的行为,所以不要这样做。
答案 2 :(得分:2)
它将调用未定义的行为。如果您没有x=NULL
,则x
将指向无效的内存位置,如果您尝试使用该位置将导致未定义的行为。
答案 3 :(得分: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 *
如您所见,地址保持不变,但第二次删除以运行时错误结束。行为可能在很大程度上取决于环境,但作为一般规则它不会起作用。
答案 4 :(得分:1)
在已删除的内存上调用delete将导致未定义的行为。通常,您的程序会崩溃。
删除x后,它将指向“编译器相关”。在调用delete之前,大多数编译器都会让它指向它的位置。但是该内存地址不再有效,因此不应该被调用。
出于同样的原因,如果需要的话,必须非常谨慎和谨慎地使用“删除这个”。 : - )
答案 5 :(得分:1)
第二次删除未定义。
作为旁注,有一些工具可以检测双重删除。其中最好的一个是Valgrind。