是`*((*(&安培;阵+ 1)) - 1)`使用安全得到一个自动数组的最后一个元素? [英] Is `*((*(&array + 1)) - 1)` safe to use to get the last element of an automatic array?
问题描述
假设我想获得一个自动数组,其大小未知的最后一个元素。我知道我可以使用的sizeof
运算符来获得数组的大小,并相应获得的最后一个元素。
Suppose I want to get the last element of an automatic array whose size is unknown. I know that I can make use of the sizeof
operator to get the size of the array and get the last element accordingly.
中使用 *((*(&安培;阵+ 1)) - 1)?
安全
Is using *((*(&array + 1)) - 1)
safe?
我爱:
char array[SOME_SIZE] = { ... };
printf("Last element = %c", *((*(&array + 1)) - 1));
int array[SOME_SIZE] = { ... };
printf("Last element = %d", *((*(&array + 1)) - 1));
等
推荐答案
我相信这是彼得提到了他的回答。
I believe it's undefined behavior for the reasons Peter mentions in his answer.
有一个巨大的辩论正在进行关于 *(&安培;阵+ 1)
。在一方面,提领&放大器;阵列+ 1
似乎是合法的,因为它只是改变从类型T(*)[]
回 T []
,但在另一方面,它仍然是一个指针未初始化的,未使用和未分配的内存。
There is a huge debate going on about *(&array + 1)
. On the one hand, dereferencing &array + 1
seems to be legal because it's only changing the type from T (*)[]
back to T []
, but on the other hand, it's still a pointer to uninitialized, unused and unallocated memory.
我的答案依赖于以下内容:
My answer relies on the following:
C99 6.5.6.7(加法运算符的语义)
有关这些操作符的目的,一个指针到一个对象,该对象是
不是一个数组中的一个元素的行为相同的指针第一
一个长度的阵列与对象为一体的类型的元件其
元素的类型。
For the purposes of these operators, a pointer to an object that is not an element of an array behaves the same as a pointer to the first element of an array of length one with the type of the object as its element type.
由于&放大器;阵列
不是指向一个对象,它是一个数组中的一个元素,然后根据这一点,就意味着code是等效于:
Since &array
is not a pointer to an object that is an element of an array, then according to this, it means that the code is equivalent to:
char array_equiv[1][SOME_SIZE] = { ... };
/* ... */
printf("Last element = %c", *((*(&array_equiv[0] + 1)) - 1));
这就是&放大器;阵列
是一个指向10个字符数组,所以它的行为一样的指针长度为1的数组的第一个元素其中每个元素都是10字符数组。
That is, &array
is a pointer to an array of 10 chars, so it behaves the same as a pointer to the first element of an array of length 1 where each element is an array of 10 chars.
现在,与后面的条款(在其他的答案已经提到在一起,这个确切的摘录公然从 ameyCU的答案被盗一>)
Now, that together with the clause that follows (already mentioned in other answers; this exact excerpt is blatantly stolen from ameyCU's answer):
C99第6.5.6.8 -
[...]结果
如果EX pression p指向数组对象的最后一个元素,前pression(P)+1分[...]结果
如果结果点中的一个过去的数组对象的最后一个元素,它不应被用作目*运算符被评估的操作数。
使得pretty清楚,这是UB:它相当于该提领点中的一个过去的 array_equiv
的最后一个元素的指针
Makes it pretty clear that it is UB: it's equivalent to dereferencing a pointer that points one past the last element of array_equiv
.
是的,在现实世界中,它的可能的工作,如在现实中原来的code并没有真正解除引用的内存位置,它主要是从类型转换T(*)[]
到 T []
,但我pretty确保但从严格的标准符合性点,这是不确定的行为。
Yes, in real world, it probably works, as in reality the original code doesn't really dereference a memory location, it's mostly a type conversion from T (*)[]
to T []
, but I'm pretty sure that from a strict standard-compliance point of view, it is undefined behavior.
这篇关于是`*((*(&安培;阵+ 1)) - 1)`使用安全得到一个自动数组的最后一个元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!