无效指针再次变为有效

use*_*ica 26 c undefined-behavior

int *p;
{
    int x = 0;
    p = &x;
}
// p is no longer valid
{
    int x = 0;
    if (&x == p) {
        *p = 2;  // Is this valid?
    }
}
Run Code Online (Sandbox Code Playgroud)

在指向它的东西被释放后访问指针是未定义的行为,但是如果稍后的分配发生在同一区域会发生什么,并且您明确地将旧指针与指向新事物的指针进行比较?难道也无妨,如果我投&x,并puintptr_t比较之前?

(我知道不能保证这两个x变量占据相同的位置.我没有理由这样做,但我可以想象一个算法,你可以使用一组绝对有效的指针来交叉一组指针指针,删除过程中的无效指针.如果先前失效的指针等于已知的好指针,我很好奇会发生什么.)

Dan*_*her 13

根据我对标准的理解(6.2.4.(2))

当指针指向(或刚刚过去)的对象到达其生命周期的末尾时,指针的值变得不确定.

比较时有未定义的行为

if (&x == p) {
Run Code Online (Sandbox Code Playgroud)

因为符合附件J.2中列出的这些要点:

- 使用指向生命周期结束的对象的指针的值(6.2.4).
- 具有自动存储持续时间的对象的值在不确定时使用(6.2.4,6.7.9,6.8).

  • 呵呵。您根本不允许使用指针的值,而不仅仅是不允许取消引用它?这比我预期的限制更多。我想知道C++中的情况是怎样的;另一个答案中的 C++ 标准引用并没有说明在比较中使用“p”是否是 UB。 (2认同)

Arn*_*rtz 6

好了,这似乎是解释为两使得三个被一些人部分的问题.

首先,有人担心是否使用poitner进行比较.

正如在注释中指出的那样,仅仅使用指针是UB,因为$ J.2:表示使用指向生命周期结束的对象的指针是UB.

但是,如果这个障碍通过(在UB的范围内很好,它可以在许多平台上运行),这就是我发现的其他问题:

鉴于指针确实比较相等,代码有效:

C标准,§6.5.3.2,4:

[...]如果为指针分配了无效值,则unary*运算符的行为未定义.

虽然该位置的脚注明确说明.一个对象在其生命周期结束后的地址是一个无效的指针值,这在这里不适用,因为if它确保指针的值是地址,x因此是有效的.

C++标准,§3.9.2,3:

如果类型T的对象位于地址A,则类型为cv T*的指针(其值为地址A)被称为指向该对象,而不管该值是如何获得的.[注意:例如,超过数组末尾的地址(5.7)将被视为指向可能位于该地址的数组元素类型的无关对象.

重点是我的.

  • 那是C++,不是吗? (5认同)
  • 我认为你引用的引用并不意味着该程序是用C++定义的.如果在`&x == p`中使用`p`本身就是C++中未定义的行为,那么在比较之后,`p`根据你的引用指向`x`并不重要.未定义的行为已经发生. (3认同)