C ++-允许编译器回收已删除的指针变量吗?

时间:2018-07-28 13:42:10

标签: c++ pointers compiler-optimization delete-operator

我的问题与此类似:
Is the compiler allowed to recycle freed pointer variables?
但对于C ++。

对于C,ISO/IEC 9899:1999§6.2.4,第2段说:

  

对象的生存期是程序执行的一部分,在此期间,保证为其保留存储空间。一个对象存在,具有恒定的地址,并在其生命周期内保留其最后存储的值。如果在其生存期之外引用对象,则行为是不确定的。 指针所指向的对象达到其生命周期的尽头时,其值变得不确定

但是,查看最新的C ++标准,我找不到该问题的明确答案。

我目前的理解是,在C ++中,尽管已删除的指针所指向的内存位置确实是无效的,但除非程序员指示程序执行此操作,否则不允许更改指针本身的值。这样。

有人可以指出一些参考资料,可以为这个问题提供明确的答案吗?

1 个答案:

答案 0 :(得分:1)

如果我们有:

int * a = new int;
int * b = a;
delete a;
std::cout<< (a==b) << "\n";

标准未声明答案为true

对象a的生存期结束后,b*a的值都是不确定的。

大多数物理硬件指针实现都不在乎,但是C ++语言的定义不是根据物理硬件的作用,而是抽象的机器。在抽象机器中,ab的值是不确定的。

编译器可以自由跟踪所有指向对象的指针,并在对象生命周期结束时将其归零。至少依赖于对象寿命的指针值的任何程序都是脆弱的。

由于C ++允许使用指针的陷阱值,因此a==b比较可能会允许UB(我不确定,这只是增加了风险)。

即使除此之外,编译器也可以基于抽象机进行优化。例如,如果我们有int* guard=new int;,然后将指针与guard进行比较,则编译器证明guard被删除后,就可以继续假设所有分支,其中您将指针与{{1 }}未达到(如果允许UB;我不确定),或者返回任意的true / false值。

这种优化已经“在野外”进行了;我不确定是否会发生指向生命周期结束的对象的指针。但是您的编译器的下一个发行版可能会开始这样做。