【发布时间】:2020-09-07 00:50:02
【问题描述】:
来自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?
}
我不相信它可以是指向对象或函数的指针。不再有可以指向的对象 而且它不是函数指针。
我不相信它可以是超过对象末尾的指针。没有任何类型的指针运算,也没有涉及数组。
我不相信它可以是空指针值,因为指针不是nullptr。它仍然指向对象的存储空间,您可以使用它来执行放置new。
我不相信它可能是一个无效的指针值。无效的指针值与存储持续时间的结束相关,而不是对象的生命周期。 "A pointer value becomes invalid when the storage it denotes reaches the end of its storage duration"。存储仍然有效。
在我看来,指针没有指针值。我哪里做错了?
【问题讨论】:
-
只有第一点才有意义,恕我直言。仍然指向一个对象,尽管该对象处于无效状态。
-
@Macmade 据我了解,对象在其构造函数完成后将不复存在。编辑:我同意这可能是最有可能的答案,但我很好奇它是怎么回事。
-
f的值在析构函数的显式调用期间或由于显式调用而不会改变。由于调用了析构函数,f现在指向一个不再存在的对象。任何使用该对象的尝试(例如取消引用该指针)都会产生未定义的行为。 -
@FrançoisAndrieux - 在析构函数调用之后对象不再存在,因为析构函数调用标志着它的生命结束。析构函数调用不会更改(在销毁之前)保存对象地址的任何指针的值。
-
@FrançoisAndrieux - 该指针指向一个不再存在的对象,因为它的生命周期已经结束。它不一定是无效的指针值 - 它可以与
nullptr进行比较并测试不相等。该标准规定,在其生命周期之外使用对象会产生未定义的行为。该标准还没有说明对象生命周期结束后指针值的含义 - 这意味着,如果您尝试测试该指针的“有效性”(除了将其与nullptr进行比较),您在未定义行为的领域。
标签: c++ pointers language-lawyer lifetime