Rust Memory Safety: Ownership, Borrowing, Lifetimes, unsafe [#47-3]
이 글의 핵심
Ownership moves, shared vs mutable borrows, lifetime elision vs explicit bounds, Arc/Mutex patterns, and when unsafe is justified for FFI and performance.
Introduction: “Why fewer memory bugs in Rust?”
C++ often surfaces UAF, dangling pointers, and data races only at runtime. Rust’s ownership, borrow checker, and lifetimes reject many of these programs at compile time.
Topics:
- Ownership and move
- Shared (
&T) vs mutable (&mut T) borrows—no aliasing xor mutation - Lifetimes to tie references to valid data
unsafefor FFI and verified invariantsSend/Sync,Arc,Mutex, channels
See also: C++ vs Rust, memory model comparison.
Scenarios
- Moved value used again — prevented; no “valid but unspecified” footgun from using moved-from C++ objects incorrectly in the same way.
- Returning reference to local — caught by lifetimes.
Rcacross threads —Rcis notSend; useArc.
Ownership & move
- Each value has one owner; assignment moves by default for non-
Copytypes. - Drop runs exactly once at end of scope.
Borrow checker
- Unlimited immutable borrows or one mutable borrow—not both.
- Prevents iterator invalidation classes of bugs when rules are respected.
Lifetimes
- Tie references to valid storage; often elided, sometimes explicit
'aon structs and functions.
unsafe
- Small, reviewed blocks for FFI, intrinsics, or data structures with manual invariants.
- Unsafe does not disable borrow checking on safe Rust around it—local invariants must hold.
Concurrency
Send: safe to move to another thread.Sync: safe to share references across threads (via&T).Arc<Mutex<T>>patterns for shared mutable state (runtime locking).
Related posts
- C++/Rust interop
- C++ vs Rust
Summary
Rust trades compile-time fighting for runtime memory UB classes. Master moves, borrows, and lifetimes; treat unsafe and FFI as typed contracts with tests and reviews.