Rust programming video tutorial (Advanced) – 015_ 1 reference cycle

Time:2021-10-13

Video address

Headline address:https://www.ixigua.com/i677586170644791348…
Station B address:https://www.bilibili.com/video/av81202308/

Source address

GitHub address:https://github.com/anonymousGiga/learn_rus…

Explanation content

Reference loop to make two lists point to each other. The example code is as follows:

use std::rc::Rc;
use std::cell::RefCell;
use crate::List::{Cons, Nil};

#[derive(Debug)]
enum List {
    Cons(i32, RefCell<Rc<List>>),
    Nil,
}

impl List {
    fn tail(&self) -> Option<&RefCell<Rc<List>>> {
        match self {
            Cons(_, item) => Some(item),
            Nil => None,
        }
    }
}

fn main() {
    let a = Rc::new(Cons(5, RefCell::new(Rc::new(Nil))));

    println!("a initial rc count = {}", Rc::strong_count(&a));
    println!("a next item = {:?}", a.tail());

    let b = Rc::new(Cons(10, RefCell::new(Rc::clone(&a))));

    println!("a rc count after b creation = {}", Rc::strong_count(&a));
    println!("b initial rc count = {}", Rc::strong_count(&b));
    println!("b next item = {:?}", b.tail());

    if let Some(link) = a.tail() {
        *link.borrow_ mut() = Rc::clone(&b);    // Change a to point to B
    }

    println! ("b rc count after changing a = {}", Rc::strong_count(&b)); // Output reference count, 2
    println! ("a rc count after changing a = {}", Rc::strong_count(&a)); // Output reference count, 2

    //The following call will make an error, because the circular reference has been made above, and the compiler cannot find the tail
    // println!("a next item = {:?}", a.tail());
}

Rust programming video tutorial (Advanced) - 015_ 1 reference cycle

explain:
(1) At the end of the main function, rust will try to discard B, which will reduce the reference count of RC instances in a and B to 1. However, because a still references RC in B, the count of RC is 1 instead of 0, so the memory of RC on the heap will not be discarded, resulting in memory leakage.

(2) In the above example, the mutual reference relationship is as shown in the above figure. If you print a.tail (), you will always find it in the above loop (in the case of (, item), but it will never end (because it is a loop, you will never find a match), which will eventually cause stack overflow.

This work adoptsCC agreement, reprint must indicate the author and the link to this article

Linghu rushed