top | item 40805770

(no title)

mahkoh | 1 year ago

Provenance might be used as justification now but the actual rules are simpler and stricter. After freeing (or reallocing) a pointer, the application must not inspect the pointer value anymore. Even `new_pointer == old_pointer` is not allowed.

IIRC, one justification for this was to account for systems with non-flat memory where inspecting the value of the old pointer might cause a processor exception.

discuss

order

nine_k|1 year ago

Wow, look, move semantics! An advanced compiler could even check for that...

RustyRussell|1 year ago

> Even `new_pointer == old_pointer` is not allowed.

This is legal. But dereferencing old_pointer even after this check had passed is undefined.

anttihaapala|1 year ago

No, it is not, and it has never been OK for as long as C has been standardized by ANSI or ISO.

C89 says that "The value of a pointer that refers to freed space is indeterminate." and that behavior is undefined "upon use ... of indeterminately-valued objects", hence a compiled program can e.g. behave as if `new_pointer == old_pointer` even though the object was relocated in memory.

teo_zero|1 year ago

Would it be acceptable to save the old address as a uintptr_t before the realloc(), and compare it with the new one after?

saagarjha|1 year ago

You could do it legally, but the results are not required to be what you want them to be.

matheusmoreira|1 year ago

This is only ever a problem in hosted C and its standard library malloc and free, right? If you write freestanding C with your own memory allocator you made from scratch, then the compiler will never make such assumptions. Right?

That wheel is certainly in need of some serious reinvention anyway. This seems like a good starting point:

https://nullprogram.com/blog/2023/12/17/

Scaevolus|1 year ago

It also makes sense for an allocator that can satisfy new allocations with recently freed allocations.