Is it well-defined to use a pointer pointing to one-past-malloc?
It is well defined if p
is pointing to one past the allocated memory and it is not dereferenced.
n1570 - §6.5.6 (p8):
[...] 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.
Subtracting two pointers are valid only when they point to elements of the same array object or one past the last element of the array object, otherwise it will result in undefined behavior.
(p9):
When two pointers are subtracted, both shall point to elements of the same array object, or one past the last element of the array object [...]
The above quotes are well applicable for both dynamically and statically allocated memory.
int a[5];
ptrdiff_t diff = &a[5] - &a[0]; // Well-defined
int *d = malloc(5 * sizeof(*d));
assert(d != NULL, "Memory allocation failed");
diff = &d[5] - &d[0]; // Well-defined
Another reason that this is valid for dynamically allocated memory, as pointed by Jonathan Leffler in a comment is:
§7.22.3 (p1):
The order and contiguity of storage allocated by successive calls to the aligned_alloc
, calloc
, malloc
, and realloc
functions is unspecified. The pointer returned if the allocation succeeds is suitably aligned so that it may be assigned to a pointer to any type of object with a fundamental alignment requirement and then used to access such an object or an array of such objects in the space allocated (until the space is explicitly deallocated).
The pointer returned by malloc
in the above snippet is assigned to d
and the memory allocated is an array of 5 int
objects.