Is access to data outside the array incorrect if you are not using it?

In the algorithm I'm writing, I might have the following (simplified, of course)

int a[3] = {1,2,3}; int b = a[3]; 

when the index used to fill overflow b , I never use the value b. Is the code still incorrect? Does an explicit border check need to be performed?

+6
source share
6 answers

This code has Undefined Behavior, regardless of whether you use b . What for? Since a[3] by definition equivalent to *(a+3) . And here is a quote from the standard, which proved that *(a+3) itself is undefined, regardless of whether this value is stored, used, or left alone.

When an expression having an integral of type is added or subtracted from the pointer, the result has the form of a pointer operand. If the operand pointer points to an array element, the array is massive enough, the result indicates the offset of the element from the original element, so the difference between the indices obtained and the original elements of the array are equal to the integral expression. In other words, if the expression P points to the ith element of the array object, the expressions (P) + N (equivalently, N + (P)) and (P) -N (where N has the value n) indicate, respectively, I + The nth and inth elements are an array, if they exist. Moreover, if the expression P points to the last element of the array object, the expression (P) +1 indicates one after the last element of the array of the object, and if the expression Q points one after the last element of the array object, the expression (Q) -1 indicates the last element of the object array. If both the pointer operand and the result point to elements of the same array object or one last element of the array object, the evaluation should not be over the stream; otherwise, undeformed behavior is defined.

+5
source

Invalid, still undefined behavior. Check the boundaries.

 int b = *(a + 3); // dereferencing beyond the array bound. 
+3
source

Reading a[3] already causes undefined behavior. Since undefined behavior is never limited locally, it can already lead to the formatting of your hard drive or the computer going to a giant, carnivorous zombie.

In fact, it usually just works. But it’s easy to make a case where the end of the array marks the end of the displayed memory area, so accessing one element outside will lead to segmentation failure. This does not apply to the int array on the stack and with most heap implementations, but you should not rely on it.

(Does the address &a[3] come with undefined behavior.)

+3
source

It is still incorrect because you are accessing a memory location outside the limits in order to get the value of a[3] and store it in the variable b .

The fact that you never use b may mean that the compiler optimizes this line of code, so you may never see any side effects from this line.

However, the compiler is not required to do this, and the code itself still has undefined behavior.

+2
source

Yes.

You use the value by copying it to b .

In particular, dereferencing (a+3) unacceptable, since expression (a+3) not a valid pointer ... and expression a[3] equivalent to *(a+3) (where a decomposed into a pointer-expression).

+1
source

Yes, it is wrong to read a[3] , which does not come out.

Using b also wrong, but it's already too late.

0
source

Source: https://habr.com/ru/post/891970/


All Articles