One-byte-off pointer still valid in C?

牧云@^-^@ 提交于 2019-11-28 08:04:29

问题


I might be mistaken, but I seem to remember that for a given memory allocation, e.g.

char *p = malloc(4);

the pointer p is a valid pointer for all bytes within the allocation and for the first byte beyond that allocation.

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

Is that correct, and where in the C Standard (link) does it say so? It seems that 6.5.9 p6 might hint into the right direction for the answer, but it's a bit fuzzy still.


回答1:


This answer assumes that p is a char *.

but for pointer comparison &( p[4] ) would be also be valid.

The pointer p + 4 (or &( p[4] ) is valid for comparison to p + N when N is in {0, 1, 2, 3, 4} with <, <=, or ==. This is noted in C11 6.5.8: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.

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

Two pointers compare equal 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 its beginning) or function, both are pointers to one past the last element of the same array object, or one is a pointer to one past the end of one array object and the other is a pointer to the start of a different array object that happens to immediately follow the first array object in the address space.109)

109) Two objects may be adjacent in memory because they are adjacent elements of a larger array or adjacent members of a structure with no padding between them, or because the implementation chose to place them so, even though they are unrelated. If prior invalid pointer operations (such as accesses outside array bounds) produced undefined behavior, subsequent comparisons also produce 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 rici pointed out, the only allowance for p + 4 to be equal to q is if q is “the start of a different array object that happens to immediately follow…”. Since NULL is not the address of any object, it follows that p + 4 == NULL is false).

This blog post looks at this and other pointer comparisons in C.




回答2:


&p[4], or p + 4 is a valid pointer, but it can't be derefrenced.

C11 6.5.6 Additive operators

[...] 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.



来源:https://stackoverflow.com/questions/22343521/one-byte-off-pointer-still-valid-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!