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
我认为并没有指向数组对象。