Pointer arithmetic still working outside of an array?

I always read that pointer arithmetic is defined until you leave the boundaries of the array. I'm not sure I fully understand what this means, and I was a little worried. Hence this question.

Suppose I start with a pointer to the beginning of an array:

int *p = (int*) malloc(4 * sizeof(int)); 

Now I create two new pointers that lie outside the array:

 int *q = p + 10; int *r = p - 2; 

Now the pointers are q-10 , q-9 , ..., r+2 , r+3 , etc. they all lie inside the boundaries of the array. Are they valid? For example, is r[3] guaranteed to give the same result as p[1] ?

I did some testing and it works. But I want to know if this is covered by the usual C specifications. In particular, I use Visual Studio 2010, Windows, and I program in native C (not C ++). Am I covered?

+8
source share
3 answers

What you are doing is working on the implementation you are using, as well as most of the most popular implementations, but does not match C. As quoted by chris,

§6.5.6 / 8: If both pointer operands and the result point to elements of the same array object or one after the last element of the array object, the evaluation should not lead to overflow; otherwise the behavior is undefined

The fact that it is undefined is likely to become more important in the future, with more advanced static analysis allowing compilers to turn this type of code into fatal errors without spending any runtime.

By the way, the historical reason for subtracting pointers is not in the same array as undefined - this is segmented memory (I think 16-bit x86, those familiar with it will want to think about a "large" memory model). Although pointers can include a segment component and offsets, the compiler can only perform arithmetic on the offset component to avoid overhead. This makes arithmetic between pointers not in the same segment invalid, as the "high part" of the difference is lost.

+9
source

According to the C11 standard, §6.5.6 / 8 (I put the first part for context):

When an expression that has an integer type is added or subtracted from the pointer
...
If both pointer operands and the result point to elements of the same array object or one after the last element of the array object, the evaluation should not lead to overflow; otherwise, the behavior is undefined.

Therefore, a result that is outside the array, and not one after the end, is undefined behavior.

+5
source

"Yes" the conditions you specified are described in the specifications.

     int * r = p - 2; 

r are the outer boundaries of the array p, the results of the evaluation in the distribution of the position by r, 2 int positions behind / before the address p.

  `r [3]` is simply the "4th" int position after the address of r 
-one
source

All Articles