DEV Community

Chanh Le
Chanh Le

Posted on

Rust ownership: another way to manage memory

In Java, we have the garbage collector helps us to clean up unused memory. In C++, we have to allocate and de-allocate memory explicitly using pointers. So, what about Rust? Ownership is a core concept in Rust which we developers, would use to ensure memory safety.

What is memory management

Memory in programming has two types: stack and heap. Because stack memory is managed automatically, we will only care about managing data (dynamically sized data) on heap memory.
Memory management is the way we allocate and de-allocate memory for storing variable values, for example values of string or linked-list variables.

JVM garbage collector (Java)

In Java, we don't have to know about how to manage memory because that is the job of JVM's garbage collector. This component of JVM will periodically scan for unused references (variables) and un-reference(de-allocate) them. So, the memory would be clean up automatically.

C++ pointer

In C++, we have to manage the memory manually and explicitly using pointer. When we need memory for a variable, we ask for a memory allocation by using the new keyword. We will receive a pointer to reference to the location where our data would be stored. Then, when the variable is no more needed (out of scope), we will use delete keyword to un-reference the pointer. So, the memory at that location would be cleaned up and released. And if we forgot to delete the pointer, that segment of memory would never be released. Eventually, we would encounter memory leak problems.

new and delete in C++:

int* pointer_name = new int(10); // ask for heap memory allocation
// Code using pointer_name variable
delete pointer_name; // de-allocate the memory segment
Enter fullscreen mode Exit fullscreen mode

Rust ownership

Ownership

Each value in Rust has an owner. The owner here is actually the variable associated with that value. When we assign a variable to another variable, the ownership is transferred.

let hello_str = "hello";
// `hello_str` variable is the owner of the heap segment storing value `hello`
Enter fullscreen mode Exit fullscreen mode

Ownership transferring

When ownership is transferred or moved, the original variable becomes invalid and unusable. Variable assignment and parameter passing would trigger ownership transfer.

let hello_str = "hello";
let new_hello_str = hello_str;
// `new_hello_str` is now the owner, `hello_str` is no more usable
Enter fullscreen mode Exit fullscreen mode

Reference borrowing

In case you just want to use the value and not want to take ownership, you could borrow a reference (&) to that value. If you also want to modify the value, you could borrow a mutable reference(&mut) instead.

fn greeting(name: &str) {
    let mut greeting_str = String::from("hello ");
    greeting_str.push_str(name);
    println!("{}", greeting_str);
}
fn main() {
    let name = "Chanh";

    // Create a reference to the name string
    let name_ref = &name;

    // Pass the reference to the greeting function
    greeting(name_ref);

    // The original name can still be used
    println!("My name is: {}", name);

}
Enter fullscreen mode Exit fullscreen mode

Copy/Clone

In case you do want to have ownership on a value, but in the same time do not want make the original variable invalid, you could copy the value to a new memory location using clone method. You would assign the ownership to a new local variable and have a full control on it without any affect on the original variable.

fn greeting(name: &mut String) {
    name.insert_str(0, "Mr. ");

    let mut greeting_str = String::from("hello ");
    greeting_str.push_str(name);

    println!("{greeting_str}");
}
fn main() {
    let name = String::from("Chanh");

    // Pass the mutable reference of the cloned value to the greeting function
    greeting(&mut name.clone());

    // The original name can still be used
    println!("My name is: {}", name);
}
Enter fullscreen mode Exit fullscreen mode

Summary

As you could see, Rust uses a new approach for managing memory allocation. The developers do not have support on cleaning data up automatically like in Java. They also do not need to manually, explicitly do that like in C++. Instead, they need to participate on helping the Rust Ownership System to know when which memory segment should be cleaned and freed.

Resources

Top comments (1)

Collapse
 
tristonarmstrong profile image
Triston Armstrong

Great read, nice work :D