Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

May I take the address of the one-past-the-end element of an array? [duplicate]

Possible Duplicate:
Take the address of a one-past-the-end array element via subscript: legal by the C++ Standard or not?

int array[10];

int* a = array + 10;   // well-defined
int* b = &array[10];   // not sure...

Is the last line valid or not?

like image 335
fredoverflow Avatar asked Jun 29 '10 21:06

fredoverflow


People also ask

Can you reference past the last element in an array?

It is legal. According to the gcc documentation for C++, &array[5] is legal. In both C++ and in C you may safely address the element one past the end of an array - you will get a valid pointer.

Is it valid to address one element beyond the end of an array?

Yes. If you have an array a[MAX] (in which MAX is some value known at compile time), the first element is a[0], and the last element is a[MAX-1]. This arrangement is different from what you would find in some other languages.


4 Answers

Yes, you can take the address one beyond the end of an array, but you can't dereference it. For your array of 10 items, array+10 would work. It's been argued a few times (by the committee, among others) whether &array[10] really causes undefined behavior or not (and if it does, whether it really should). The bottom line with it is that at least according to the current standards (both C and C++) it officially causes undefined behavior, but if there's a single compiler for which it actually doesn't work, nobody in any of the arguments has been able to find or cite it.

Edit: For once my memory was half correct -- this was (part of) an official Defect Report to the committee, and at least some committee members (e.g., Tom Plum) thought the wording had been changed so it would not cause undefined behavior. OTOH, the DR dates from 2000, and the status is still "Drafting", so it's open to question whether it's really fixed, or ever likely to be (I haven't looked through N3090/3092 to figure out).

In C99, however, it's clearly not undefined behavior.

like image 136
Jerry Coffin Avatar answered Oct 05 '22 23:10

Jerry Coffin


As other answers have indicated, the expression array[10] is equivalent to *(array + 10), which would appear to result in an undefined dereferencing of the element just past the end of the array. however, the expression &array[10] is equivalent to &*(array + 10), and the C99 standard makes clear (6.5.3.2 Address and indirection operators):

The unary & operator returns the address of its operand. If the operand has type ‘‘type’’, the result has type ‘‘pointer to type’’. If the operand is the result of a unary * operator, neither that operator nor the & operator is evaluated and the result is as if both were omitted, except that the constraints on the operators still apply and the result is not an lvalue. Similarly, if the operand is the result of a [] operator, neither the & operator nor the unary * that is implied by the [] is evaluated and the result is as if the & operator were removed and the [] operator were changed to a + operator.

So, there's nothing undefined about &array[10] - there is no dereference operation that takes place.

like image 31
Michael Burr Avatar answered Oct 06 '22 00:10

Michael Burr


No. It's undefined. array[10] amounts to *(array + 10). In other words, you've dereferenced an invalid pointer.

like image 34
Edward Strange Avatar answered Oct 05 '22 23:10

Edward Strange


array[10] is equivalent to *(array + 10) (and also equivalent to 10[array]), so &array[10] acts like removing the * from *(array+10). Any decent compiler should emit the same code (and the same warning).

like image 30
Cogwheel Avatar answered Oct 05 '22 22:10

Cogwheel