Why is the arithmetic behavior of the out-of-bounds pointer undefined?

The next example is from Wikipedia .

int arr[4] = {0, 1, 2, 3}; int* p = arr + 5; // undefined behavior 

If I never look for p, then why is arr + 5's behavior only undefined? I expect pointers to behave like integers - except that when dereferenced, the value of the pointer is considered a memory address.

+18
c ++ undefined-behavior
May 6 '12 at 19:32
source share
5 answers

This is because pointers do not behave like integers. This behavior is undefined because the standard talks about it.

However, on most platforms (if not all), you will not be able to crash or run into questionable behavior if you do not find the array. But then, if you do not play it, what's the point of making an addition?

However, note that the expression following one end of the array is technically 100% “correct” and guaranteed to not fail in §5.7 ¶5 of the C ++ 11 specification. However, the result of this expression is not specified (it simply will not guarantee overflow) ; while any other expression that goes more than one beyond the bounds of the array is explicitly undefined.

Note. This does not mean that it is safe to read and write due to bias. You will probably be editing data that does not belong to this array and will cause state / memory corruption. You simply will not throw an overflow exception.

I guess this is because it is not only acting out this wrong. Also pointer arithmetic, pointer comparison, etc. So just say don't do it , and not list situations where it can be dangerous.

+15
May 6 '12 at 19:34
source share

The original x86 may have problems with such statements. In a 16-bit code, pointers have 16 + 16 bits. If you add an offset to the lower 16 bits, you may need to overflow and change the upper 16 bits. It was a slow operation and should be avoided.

On these systems, array_base+offset not guaranteed to overflow if the offset is in the range (<= array size). But array+5 will overflow if the array contains only 3 elements.

The consequence of this overflow is that you got a pointer that does not point to an array, but earlier. And it may not even be RAM, but hardware with memory mapping. The C ++ standard does not attempt to limit what happens if you create pointers to random hardware components, i.e., Undefined Behavior on real systems.

+12
May 7 '12 at 9:37
source share

“Undefined behavior” does not mean that it should fall on this line of code, but it does mean that you cannot guarantee that the result will be guaranteed. For example:

 int arr[4] = {0, 1, 2, 3}; int* p = arr + 5; // I guess this is allowed to crash, but that would be a rather // unusual implementation choice on most machines. *p; //may cause a crash, or it may read data out of some other data structure assert(arr < p); // this statement may not be true // (arr may be so close to the end of the address space that // adding 5 overflowed the address space and wrapped around) assert(p - arr == 5); //this statement may not be true //the compiler may have assigned p some other value 

I am sure there are many other examples here.

+4
May 6 '12 at 19:39
source share

If arr is on the right side of the machine’s memory space, then arr+5 may be outside this memory space, so the pointer type may not display the value, that is, it may overflow, and the overflow is undefined.

+3
May 6 '12 at 19:37
source share

Some systems, very rare systems, and I can't name them, will cause traps when you push the boundaries. In addition, it allows an implementation that provides border protection, exists ... again, although I cannot think about it.

Essentially, you should not do this, and therefore there is no reason to indicate what happens when you do this. Indication of what is happening creates an unreasonable burden on the implementation provider.

+2
May 6 '12 at 20:53
source share



All Articles