In Rust, resource management and cleanup are implemented through a system called ownership, one of Rust's core features. Rust prevents common errors such as memory leaks and dangling pointers using its ownership rules and related mechanisms, including borrowing and lifetimes.
Ownership System
Ownership Rules
Each value in Rust has exactly one owner at any given time. When the owner goes out of scope, the value is dropped, and associated resources are automatically released.
Example
rustfn main() { let string1 = String::from("Hello"); // string1 is the owner { let string2 = string1; // Ownership is transferred from string1 to string2 // string1 is no longer valid at this point } // When string2 goes out of scope, the memory it owns is released }
In the above example, string1 initially owns the string "Hello". When string1 is assigned to string2, ownership transfers to string2, making string1 invalid and unusable. When string2 exits its scope, its internal data is automatically cleaned up, and memory is released.
Borrowing
Immutable Borrowing
You can have multiple immutable borrows of the same resource, but the original data cannot be modified during any borrow.
Mutable Borrowing
You can mutably borrow a resource, but no other borrows (including immutable ones) are permitted during this borrow.
Example
rustfn main() { let mut s = String::from("hello"); let r1 = &s; // Immutable borrow let r2 = &s; // Immutable borrow println!("{} and {}", r1, r2); // let r3 = &mut s; // Error: cannot have a mutable borrow while an immutable borrow exists }
Lifetimes
Example
rustfn main() { let r; // Declare a reference { let x = 5; // x's lifetime begins r = &x; // Error: x's lifetime is shorter than r's } // x goes out of scope and is dropped }
In the above example, x has a shorter lifetime than r, so when x goes out of scope, r points to a destroyed value. This is invalid and will be caught by the compiler.
Through these three mechanisms—ownership, borrowing, and lifetimes—Rust effectively manages resources, preventing memory leaks and other common memory errors while reducing the burden on programmers for manual memory management.