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,并p以uintptr_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).
好了,这似乎是解释为两使得三个被一些人部分的问题.
首先,有人担心是否使用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)将被视为指向可能位于该地址的数组元素类型的无关对象.
重点是我的.