Which reason best explains why Rust uses smart pointers like Box or Rc instead of raw pointers?
Think about what problems can happen if you manually manage memory with raw pointers.
Smart pointers in Rust help manage memory safely by automatically freeing memory when no longer used, avoiding common bugs like double frees or dangling pointers.
What is the output of this Rust code?
fn main() {
let x = Box::new(10);
println!("{}", *x + 5);
}Remember that Box stores the value on the heap and you can access the value by dereferencing.
The Box smart pointer holds the value 10 on the heap. Using *x dereferences it to 10, then adding 5 gives 15.
What error will this Rust code produce?
fn main() {
let mut x = 5;
let r1 = &x as *const i32;
let r2 = &mut x as *mut i32;
unsafe {
*r2 = 10;
println!("{}", *r1);
}
}Raw pointers allow unsafe code but you must be careful with aliasing rules.
This code uses raw pointers and unsafe block. It writes 10 through the mutable pointer and reads through the const pointer. It prints 10 without compile error, but this is unsafe and can cause undefined behavior if misused.
Why does Rust use smart pointers like Rc and Arc instead of a garbage collector?
Think about how Rust manages memory without a background process cleaning unused data.
Rust uses smart pointers to manage memory with clear ownership and reference counting, avoiding the runtime cost and unpredictability of garbage collection.
Consider this Rust code using Rc smart pointer:
use std::rc::Rc;
fn main() {
let a = Rc::new(5);
let b = Rc::clone(&a);
let c = Rc::clone(&b);
drop(b);
println!("{}", Rc::strong_count(&a));
}What number will be printed?
Count how many Rc pointers are alive after dropping one.
Initially, a has 1 strong count. Cloning twice makes 3. Dropping b reduces count to 2. So printing strong_count(&a) outputs 2.