In C, it is perfectly well to make a pointer that points to one past the last element of an array and use it in pointer arithmetics, as long as you don't dereference it:
int a, *p = a+5, diff = p-a; // Well-defined
p = a+6;
int b = *(a+5), diff = p-a; // Dereferencing and pointer arithmetic
int *a = malloc(5 * sizeof(*a));
assert(a != NULL, "Memory allocation failed");
int *p = a+5;
int diff = p-a; // Use in pointer arithmetic?
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.
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; ptrdiff_t diff = &a - &a; // Well-defined int *d = malloc(5 * sizeof(*d)); assert(d != NULL, "Memory allocation failed"); diff = &d - &d; // Well-defined
The order and contiguity of storage allocated by successive calls to the
reallocfunctions 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