In Standard C and C++, the address of the first element past the end of an array can be used in pointer arithmetic. Thus, you can initialize a vector with the contents of a built-in array, like this:
int arr[3] = {1, 2, 3}; vector vi ( arr, //address of the array's beginning arr + 3 ); // address of one element past the array's end
Now consider an almost identical version of this example:
vector vi ( &arr[0], //address of the array's beginning &arr[3] ); // address of one element past the array's end
Both forms seem to be correct and identical but they are not. While the Standard allows you to take the address of one element past the array’s end (as shown in the first example), the second example does something different. To understand the difference, it is important to know how precisely the expression &arr[3] is interpreted. First, the subexpression arr[3] is evaluated to *(arr+3), that is, the element located one position past the array’s end is read. However, no such element exists. Next, the address of the non-existent element is taken. In other words, &arr[3] is equivalent to &(*(arr+3)), which is very different from arr+3. The first example is legal, while the other is undefined (although in practice, it will work on most compilers as expected).
Most experienced C and C++ programmers are surprised that &arr[3] isn’t completely equivalent to arr+3. In fact, it even surprised the C committee, who heard about the issue only recently. Hopefully, this loophole will be fixed in the upcoming revision of the C standard.