#include <stddef.h>
#include <stdlib.h>
int main(void)
{
const size_t length = 10000;
double* a = malloc(length * sizeof *a);
double* first = a;
double* last = a + length-1;
free(a);
ptrdiff_t diff = last - first;
}
In C, is it well-defined to take the difference of two pointers pointing to some locations in the same array after it has been deallocated?
The reason I am asking this is because I have an array of pointers pointing to the same buffer. The buffer gets reallocated, and I need to update the pointers. I do this by computing the difference between pointer n and pointer 0 in the pointer array after the buffer is reallocated. (Of course I can compute the differences before reallocation and store it, but I am a bit curious.)
In C, is it well-defined to take the difference of two pointers pointing to some locations on the same array after it has been deallocated?
The answer is no for the C language. Here are the references from the C Standard:
6.2.4 Storage durations of objects
1 An object has a storage duration that determines its lifetime. There are four storage durations: static, thread, automatic, and allocated. Allocated storage is described in 7.24.4.
2 The lifetime of an object is the portion of program execution during which storage is guaranteed to be reserved for it. An object exists, has a constant address, and retains its last-stored value throughout its lifetime. If an object is referred to outside of its lifetime, the behavior is undefined. If a pointer value is used in an evaluation after the object the pointer points to (or just past) reaches the end of its lifetime, the behavior is undefined. The representation of a pointer object becomes indeterminate when the object the pointer points to (or just past) reaches the end of its lifetime.[...]
7.24.4 Memory management functions
[...] The lifetime of an allocated object extends from the allocation until the deallocation
3.25
1 indeterminate representation object representation that either represents an unspecified value or is a non-value representation
The Standard is clear: If a pointer value is used in an evaluation after the object the pointer points to (or just past) reaches the end of its lifetime, the behavior is undefined. So you cannot use the pointers to compute the offset into the deallocated array.
This may seem extravagant as pointer values should not magically change when the block they point into is freed and pointer arithmetic should still work and produce the expected values. In most cases, it will and you are unlikely to experience this kind of undefined behavior on regular environments, but the Standard hints that The representation of a pointer object becomes indeterminate when the object the pointer points to (or just past) reaches the end of its lifetime. This means that merely using the pointer value can have undefined behavior, eg: because they could be trap values.
Here are a few examples of environments where this could pose problems:
So the answer is no and here are possible solutions:
realloc, while the pointers are still valid.realloc to reallocate the block; use malloc to allocate a new block and copy the contents explicitly (you should know the required length) and update the other pointers before freeing the old block.uint32_t indices for half the cache footprint of pointers or size_t indices.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With