A retained value need not designate a live object

Destruction or deallocation can leave a program with a value referring to the former location. That value does not automatically become null. A null check alone therefore cannot establish that the former object remains usable.

The C++ working draft distinguishes null, object-related, and invalid pointer values, with validity tied to storage duration and use. Languages also differ in restrictions on evaluating invalid pointers; avoiding dereference is not a universal justification for every other operation.

References: [1] [2]

Deallocation is not the only cause

Returning an address or reference to a local value without keeping that value alive is another source. The Rust Book illustrates this with a reference to a local String: returning a reference does not extend the String’s existence after function cleanup.

Use-after-free describes an invalid access after deallocation, while a dangling pointer describes a retained value without its former valid target. The concepts overlap but are not identical, and local-object expiry provides a different lifetime path.

References: [3] [4] [2]

Validity must cover every permitted use

A repair must establish whether callers need temporary access, shared ownership, or an independent value. Returning an owned value, retaining a suitable owner, or using managed sharing can express that requirement more clearly than returning an unconstrained raw location.

Borrow checking can reject dangling-reference patterns, and dynamic tools detect selected executed stack or heap lifetime errors. Neither determines the intended business lifetime for the program. Interfaces must still specify who maintains validity, who may release the object, and when access ends.

References: [5] [3] [6]