Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is comparing to a pointer one element past the end of an array well-defined?

I learned by this question that incrementing a NULL pointer or incrementing past the end of an array isn't well-defined behavior:

int* pointer = 0;
pointer++;

int a[3];
int* pointer2 = &a[0];
pointer2 += 4; 

But what If the pointer pointing to a invalid place is only used for comparison and memory at his location is never accessed?

Example:

void exampleFunction(int arrayLen, char** strArray)
{
    for(char** str = strArray; str < strArray + arrayLen; str++) //or even str < &strArray[arrayLen]
    {
        //here *str is always a pointer to the first char of my string
    }
}

Here I compare my pointer to a pointer one element past the end of the array. Is this well-defined behavior?

like image 755
Winter Avatar asked Jul 26 '17 19:07

Winter


People also ask

Can pointer point one past the end of an object?

it is possible for a pointer to an object and a pointer one past the end of a different object to hold the same address.

What happens when you dereference a pointer to an array?

Pointer to an array points to an array, so on dereferencing it, we should get the array, and the name of array denotes the base address. So whenever a pointer to an array is dereferenced, we get the base address of the array to which it points.

What is the relationship between pointer and array?

An array is represented by a variable that is associated with the address of its first storage location. A pointer is also the address of a storage location with a defined type, so D permits the use of the array [ ] index notation with both pointer variables and array variables.

Does a pointer to an array point to the first element?

This pointer points to the first element in the array. You can dereference that pointer to access the array element. Pointer variables that point into an array can also be moved around in the array via the pointer increment and decrement operations.


1 Answers

Comparing to a pointer one step past the end of an array is well defined. However, your pointer and pointer2 examples are undefined, even if you do literally nothing with those pointers.

A pointer may point to one element past the end of the array. That pointer may not be dereferenced (otherwise that would be undefined behavior) but it can be compared to another pointer within the array.

Section 6.5.6 of the C standard says the following regarding pointer addition (emphasis added):

8 If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is undefined. If the result points one past the last element of the array object, it shall not be used as the operand of a unary * operator that is evaluated.

Section 6.5.8 says the following regarding pointer comparisons (emphasis added):

5 When two pointers are compared, the result depends on the relative locations in the address space of the objects pointed to. If two pointers to object types both point to the same object, or both point one past the last element of the same array object, they compare equal. If the objects pointed to are members of the same aggregate object, pointers to structure members declared later compare greater than pointers to members declared earlier in the structure, and pointers to array elements with larger subscript values compare greater than pointers to elements of the same array with lower subscript values. All pointers to members of the same union object compare equal. If the expression P points to an element of an array object and the expression Q points to the last element of the same array object, the pointer expression Q+1 compares greater than P. In all other cases, the behavior is undefined.

In the case of pointer1, it starts out pointing to NULL. Incrementing this pointer invokes undefined behavior because it don't point to a valid object.

For pointer2, it is increased by 4, putting it two elements past the end of the array, not one, so this is again undefined behavior. Had it been increased by 3, the behavior would be well defined.

like image 122
dbush Avatar answered Sep 20 '22 01:09

dbush