C 是否允许对不再拥有的数组执行指针算术?

C 是否允许对不再拥有的数组执行指针算术?,c,C,考虑 int main() { char* p = malloc(5); printf("%td", &p[5] - &p[0]); /*one past the end is allowed*/ free(p); printf("%td", &p[5] - &p[0]); /*I no longer own p*/ } 是否定义了此代码的行为?允许您在不再拥有的数组上执行指针算术吗?是的,通常允许您在许多环境中的许多编译器上执行

考虑

int main()
{
    char* p = malloc(5);
    printf("%td", &p[5] - &p[0]); /*one past the end is allowed*/
    free(p);
    printf("%td", &p[5] - &p[0]); /*I no longer own p*/
}

是否定义了此代码的行为?允许您在不再拥有的数组上执行指针算术吗?

是的,通常允许您在许多环境中的许多编译器上执行指针算术


但是,您必须记住,当您这样做时,ISO C标准对您的语言没有任何要求:它没有定义任何使用值为“不确定”的指针的行为。根据ISO C,在
free(p)
之后的
p
值基本上与未初始化的状态相同。

您是在寻找语言律师答案,还是实际答案

语言律师的回答是,不,没有定义


实际的答案是:是的,它可能会起作用,但这是个坏主意。在释放指针之前,我总是会计算差值(必要时将其存储在变量中)。

您可以进行算术运算。你可能再也不能访问数组了。你从哪里得到的
p[5]
是允许的(最后一个???)可能重复的@PaulOgilvie——即使是
p+1
之外的指针算术在
p
释放后也是未定义的行为。@FitzwilliamBennet-Darcy:没错。然而,当指针超出对象的范围(不管是堆栈还是堆分配的)时,即使计算指针本身(比如指针算法)也是未定义的行为。换句话说,指针,即使没有取消引用,也必须指向对象中的某个位置,或紧跟在该位置之后的位置。因此,您的代码是未定义的行为。许多(大多数?)编译器在实践中确实允许它,但我不会指望它。”……它没有定义……”我同意,但似乎无法在C11标准中找到相关段落。6.5.6/8我觉得有点模棱两可。@alk--关于§6.5.6 9:“当减去两个指针时,两个指针都应指向同一数组对象的元素,或指向数组对象最后一个元素的一个……”在
free(p)之后
p
我认为并没有指向数组对象。