Summary
This was another long chapter. We learned about all the smart pointer types that modern systems programming languages offer to make memory management simpler, while still retaining performance comparable to a hand-rolled implementation. The main types are slices, smart pointers (both single-ownership and multiple-ownership) and weak pointers. As a cheat sheet, here is an overview of the related types in both C++ and Rust, and what they are used for:
Memory-Model | Rust Type(s) | C++ Type(s) | Low-level equivalent |
---|---|---|---|
Single value on heap/stack, borrowed | &T and &mut T | const T& and T& | T* |
Single value on heap, single owner | Box<T> | std::unique_ptr<T> | T* |
Single value on heap, multiple owners | Rc<T> and Weak<T> , potentially with Cell<T> or RefCell<T> | std::shared_ptr<T> and std::weak_ptr<T> | T* |
Multiple adjacent values on heap/stack, borrowed | [T] in general and str for Strings | std::span<T> in general and std::basic_string_view<T> for Strings | T* + size_t length; |
Multiple adjacent values on heap, single owner | Vec<T> | std::vector<T> | T* + size_t length; |
Multiple adjacent values on heap, multiple ownersEach owner owns all the values, because the underlying memory region is obtained with a single call to e.g. malloc() . | Rc<Vec<T>> | std::shared_ptr<std::vector<T>> | T* + size_t length; |