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-ModelRust Type(s)C++ Type(s)Low-level equivalent
Single value on heap/stack, borrowed&T and &mut Tconst T& and T&T*
Single value on heap, single ownerBox<T>std::unique_ptr<T>T*
Single value on heap, multiple ownersRc<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 Stringsstd::span<T> in general and std::basic_string_view<T> for StringsT* + size_t length;
Multiple adjacent values on heap, single ownerVec<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;