tezvyn:

Rust references vs raw pointers

AI-drafted, machine-checkedSource: interviewintermediate
WHAT IT TESTS

safety invariants of references.

OUTLINE

references are borrow-checked, always valid, aliasing-controlled, non-null; raw pointers carry no guarantees, can be null, dangling, or aliased, and dereferencing needs unsafe.

WHAT THIS TESTS Whether you understand the safety invariants the borrow checker attaches to references and exactly which of those you forfeit when working through raw pointers in unsafe code.

A GOOD ANSWER COVERS References &T and &mut T carry strong compiler-enforced guarantees: they are never null, always properly aligned, always point to a valid initialized value for the duration of their lifetime, and obey the aliasing rule of either many shared references or exactly one mutable reference at a time. Lifetimes ensure a reference can never outlive its referent, so dangling is impossible in safe code. Raw pointers *const T and *mut T deliberately drop all of this: they may be null, dangling, unaligned, or point to freed or uninitialized memory; multiple *mut to the same location may coexist; and they are not tracked by lifetimes or the borrow checker. Creating a raw pointer is safe, but dereferencing one requires an unsafe block, because the compiler can no longer prove the access is valid, so you assume responsibility for those invariants.

COMMON WRONG ANSWERS Claiming raw pointers are just references without syntactic sugar; they have entirely different guarantees. Thinking creating a raw pointer is unsafe; only dereferencing is. Believing unsafe disables the borrow checker globally; it only permits a few extra operations.

LIKELY FOLLOW-UPS What undefined behavior arises from violating aliasing or dereferencing a dangling pointer? How do you convert safely between them, and why is producing a reference from a raw pointer the dangerous step? What does NonNull add? How does this interact with FFI?

ONE CONCRETE EXAMPLE let mut x = 5; let r = &mut x as *mut i32; unsafe { *r += 1; }. Creating r is safe, but the write needs unsafe because the compiler cannot guarantee r is valid or unaliased. Misusing this, such as keeping two *mut into the same value and writing through both while a &mut also exists, is undefined behavior the compiler would have prevented for plain references.

Read the original → doc.rust-lang.org

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.