Is the single-byte pointer still valid in C?

Maybe I'm wrong, but it seems like I remember that for dedicated memory allocation, for example

char *p = malloc(4); 

pointer p is a valid pointer for all bytes in the distribution and for the first byte outside of this allocation.

Thus, for access to the memory through the pointer p , only offsets p[0] .. p[3] permissible. But to compare pointers, &( p[4] ) also be a valid pointer.

Is this correct, and where in the C-standard ( link ) does he say so? It seems like 6.5.9 p6 might hint in the right direction of the answer, but it's a bit fuzzy.

+6
source share
2 answers

This answer assumes p is char * .

but also for comparing pointers (p [4]).

Pointer p + 4 (or &( p[4] ) valid for comparison with p + N when N is in {0, 1, 2, 3, 4} with < , <= or == This is noted in C11 6.5. 8: 5:

When comparing two pointers, the result depends on the relative locations in the address space of the objects that it points to. If two pointers to types of objects point to the same object or both point one after the last element of the same array object, they compare equal ones. If the objects pointed to are members of the same aggregate object, pointers to structure elements declared later are compared more than pointers to elements declared earlier in the structure, and pointers to array elements with large index values ​​are compared more than pointers to elements of the same array with a subscript value. All pointers to members of the same union object are compared the same way. 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 expression of the pointer Q + 1 is compared to P. In all other cases, the behavior is undefined.

However, p+4 not valid for comparison with == , say, &X , where X is another variable. This (at best my standard C decryption) is unspecified behavior. (And, of course, none of p + N is suitable for comparison with <= to &X )

Two pointers compare the same if and only if both are null pointers, both are pointers to the same object (including a pointer to an object and a subobject at the beginning) or a function, both are pointers to one of the last elements of the same array object , or one is a pointer to one end of the end of one array object, and the other is a pointer to the beginning of another array object that occurs immediately after the first array object in the address space .109)

109). Two objects can be contiguous in memory, because they are contiguous elements of a larger array or neighboring structural elements without laying between them, or because the implementation chose them that way, even if they are not connected to each other. If previously invalid pointer operations (such as accessing the boundaries of an external array) caused undefined behavior, subsequent comparisons also result in undefined behavior.

(C11 6.5.9: 6)

Strictly speaking, the standard does not seem to say anywhere that p + 4 == NULL is defined either ( EDIT: as Richie pointed out, the only assumption for p + 4 q if q is "the beginning of another array object that happens immediately after ... ". Since NULL is not the address of any object, this means that p + 4 == NULL is false).

This blog post reviews this and other pointer comparisons in C.

+2
source

&p[4] , or p + 4 is a valid pointer, but it cannot be undone.

C11 6.5.6 Additive operators

[...] 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. If the result is displayed beyond the last element of an array object, it should not be used as the operand of the unary operator * , which is evaluated.

+4
source

All Articles