5 ms·
Although pointers don't have a size, every allocation has a size: int x; // &x would have size 1 int *y = malloc(5 * sizeof(int)); // Size 5 int *z
by nayuki 5y ago
Although pointers don't have a size, every allocation has a size:
int x; // &x would have size 1
int *y = malloc(5 * sizeof(int)); // Size 5
int *z = y + 2; // Size 3
int w[4]; // Size 4
A C compiler is allowed to track the size of objects in some hidden area, and that's what enables tools like AddressSanitizer and MemorySanitizer to exist.
As for pointers to already-freed objects, it is undefined behavior to read, calculate, or compare them in any way; the only legal operation is to overwrite or dispose of the pointer.
- Jweb_Guru 5y agoI am aware of all these rules, but they don't address my question. ASAN and friends add instrumentation (at significant cost) at runtime and are imperfect, especially in multithreaded programs where accesses can race with frees. My question involved another thread (for example) freeing the pointer to an underlying allocation, which was previously in-bounds. In this case, whether it was UB to construct the pointer would depend upon whether the free was synchronized with the pointer arithmetic, which is not generally something compilers can work out in nontrivial programs (though these days this stuff is amenable to formal verification).
- nayuki 5y agoC and UB are intertwined and I don't believe there is a way to solve all problems without significant compromises. Regarding how to check pointer arithmetic under multi-threading, I like Rust's approach of multiple-readers-or-single-writer, which you can't retrofit onto C's legacy pointers that can be copied arbitrarily.