Rust’s ownership model works well in most cases, but sometimes two or more objects reference each other, preventing their reference counts from ever reaching zero. As a result, the allocated memory is never released.


Node struct contains a value, an optional parent, and a list of children. Initially, we use only strong references (Rc<T>) for both parent and child relationships.
In scenarios where two entities hold strong references to each other, careful design is needed to allow proper memory deallocation. This is especially common in parent-child relationships and cyclic graph structures.
To resolve this issue, Rust provides the
Weak<T> smart pointer. Unlike Rc<T>, a weak reference does not contribute to the strong count of an object. Using weak pointers for back-references, such as the parent pointer in a tree structure, breaks the cycle and allows Rust to reclaim memory when there are no remaining strong references.

Rc<T> to a weak pointer using Rc::downgrade increments only the weak count. This allows you to later attempt to “upgrade” the weak reference back to an Rc<T> (yielding an Option<Rc<T>>) if access to the data is necessary, without preventing the object’s deallocation.

Below is an improved version of the earlier example that employs a weak pointer for the parent reference, thereby avoiding a reference cycle:
Weak<Node>, so using Rc::downgrade(&parent) does not increase the parent’s strong count. When you print the upgraded weak reference with child.parent.borrow().upgrade(), it will successfully return an Rc<Node> as long as the parent is still alive. Once all strong references to the parent are dropped, the parent will be deallocated, and the weak reference will no longer be upgradable.
Using weak pointers is especially beneficial in scenarios such as parent-child relationships or cyclic data structures where a strong back-reference could inadvertently keep an object alive. This ensures that your application remains memory efficient.
