使用指针显式调用指向对象的析构函数后,指针持有什么样的值?

Fra*_*eux 5 c++ pointers lifetime language-lawyer

来自https://timsong-cpp.github.io/cppwp/basic.compound#3

指针类型的每个值都是以下之一:

  • 指向对象或函数的指针(该指针被称为指向该对象或函数),或
  • 超过对象末尾的指针 ([expr.add]),或
  • 该类型的空指针值,或
  • 无效的指针值。

使用指针显式调用对象的析构函数后,指针具有这四种值中的哪一种?例子 :

#include <vector>

struct foo {
    std::vector<int> m;
};

int main()
{
    auto f = new foo;
    f->~foo();
    // What is the value of `f` here?
}
Run Code Online (Sandbox Code Playgroud)

我不相信它可以是指向对象或函数的指针。不再有要指向的对象,它也不是函数指针。

我不相信它可以是超出对象末尾的指针。没有任何类型的指针算术,也没有涉及数组。

我不相信它可以是空指针值,因为指针不是nullptr。它仍然指向对象所拥有的存储空间,您可以使用它来执行放置new

我不相信它可以是无效的指针值。无效的指针值与存储持续时间的结束相关联,而不是与对象生命周期相关联。“当它表示的存储达到其存储持续时间的末尾时,指针值变得无效”。存储仍然有效。

在我看来,指针可能没有指针值。我哪里做错了?

yur*_*hek 7

它是指向对象的指针,但对象不在其生命周期内。

[basic.compound],脚注 42) 中

对于不在其生命周期内的对象,这是它将占用或曾经占用的内存中的第一个字节。

  • _脚注基本上说指向存储字节的指针是指向一个对象的指针,该对象可能被构造为从该字节开始占用该存储_不,它没有这么说。它表示指向某个特定对象(生命周期之外)的指针表示该对象将占用或用于占用的字节地址。您有指向特定对象的指针,而不是“存储字节”和/或可以放置在那里的所有对象。 (2认同)

eer*_*ika 1

它是一个指针,指向不再存在的对象。在标准列出的可能值中,只有指向对象的指针可以应用,但前提是我们认为该定义中包含超出其生命周期的对象。如果可能包含指向没有对象的存储的指针,则可能适用无效。

如果这些都不适用,那么所有值的列表将是有缺陷的。


如果您要在存储中创建一个新对象,那么这将适用:

[基本生活]

如果一个对象的生命周期结束后,在该对象占用的存储空间被重用或释放之前,在原对象占用的存储位置上创建一个新的对象,一个指向原对象的指针,一个指向该对象的引用引用原始对象,或者原始对象的名称将自动引用新对象,并且一旦新对象的生命周期开始,如果原始对象是透明可替换的(请参阅如下)由新对象。