c++ - 比较悬挂指针是否合法?

标签 c++ pointers language-lawyer dangling-pointer

比较悬挂指针合法吗?

int *p, *q;
{
    int a;
    p = &a;
}
{
    int b;
    q = &b;
}
std::cout << (p == q) << '\n';

请注意 pq 如何指向已经消失的对象。这合法吗?

最佳答案

简介:第一个问题是使用p的值是否合法。

a 被销毁后,p 获得了所谓的无效指针值。引自 N4430 (关于 N4430 状态的讨论见下面的“注释”):

When the end of the duration of a region of storage is reached, the values of all pointers representing the address of any part of the deallocated storage become invalid pointer values.

使用无效指针值时的行为也包含在 N4430 的同一部分中(并且几乎相同的文本出现在 C++14 [basic.stc.dynamic.deallocation]/4 中):

Indirection through an invalid pointer value and passing an invalid pointer value to a deallocation function have undefined behavior. Any other use of an invalid pointer value has implementation-defined behavior.

[ Footnote: Some implementations might define that copying an invalid pointer value causes a system-generated runtime fault. — end footnote ]

因此您将需要查阅您的实现文档以了解此处应该发生什么(C++14 起)。

上述引用中的术语使用 means需要左值到右值的转换,如 C++14 [conv.lval/2]:

When an lvalue-to-rvalue conversion is applied to an expression e, and [...] the object to which the glvalue refers contains an invalid pointer value, the behaviour is implementation-defined.


历史:在 C++11 中,这表示未定义而不是实现定义;它被 DR1438 改变了.查看这篇文章的编辑历史以获取完整的引用。


p == q 的应用:假设我们在 C++14+N4430 中接受了 pq 是实现定义的,并且实现没有定义硬件陷阱的发生; [expr.eq]/2 说:

Two pointers compare equal if they are both null, both point to the same function, or both represent the same address (3.9.2), otherwise they compare unequal.

由于在计算 pq 时获得什么值是实现定义的,我们不能确定这里会发生什么。但它必须是实现定义的或未指定的。

在这种情况下,g++ 似乎表现出未指定的行为;根据 -O 开关,我可以让它说 10,对应于是否重新使用相同的内存地址- 在 a 被销毁后用于 b


关于 N4430 的注意事项:这是针对 C++14 的缺陷解决方案,尚未被接受。它清除了很多围绕对象生命周期、无效指针、子对象、 union 和数组边界访问的措辞。

在 C++14 文本中,在 [basic.stc.dynamic.deallocation]/4 和后续段落中定义了 无效指针值delete 被使用。然而,并没有明确说明同样的原则是否适用于静态或自动存储。

[basic.compound]/3 中有一个“有效指针”的定义,但它过于模糊,无法明智地使用。[basic.life]/5(脚注)引用了相同的文本来定义指针的行为静态存储持续时间的对象,这表明它适用于所有类型的存储。

在 N4430 中,文本从该部分向上移动了一层,以便它明确适用于所有存储期限。附有注释:

Drafting note: this should apply to all storage durations that can end, not just to dynamic storage duration. On an implementation supporting threads or segmented stacks, thread and automatic storage may behave in the same way that dynamic storage does.


我的意见: 除了说 p 获取无效指针值外,我没有看到任何一致的方式来解释标准(N4430 之前)。除了我们已经看过的内容之外,其他任何部分似乎都没有涵盖该行为。因此,在这种情况下,我很乐意将 N4430 措辞视为代表标准的意图。


关于c++ - 比较悬挂指针是否合法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33066133/

相关文章:

python - 调用函数时如何在 ctyps 中返回数组

c++ - 访问字节数组的 typedef 指针

c++ - 这是一个错误吗? constexpr 构造函数静默变为非 constexpr

c - 对象大小限制下的行为

c++ - 左值引用绑定(bind)

c++ - 基于事件的 shell 脚本

c++ - 如何用代字号替换主目录? Linux

c++ - 指向寄存器地址的指针

c++ - 在使用 boost spirit 解析时更改属性值

c++ - 如何将 boost 数组表示为类型的指针?