Rust ownership: another way to manage memory
Tags: rust, beginners, memory, ownership
Published: 2024-03-02 16:59:58

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++:
```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
```

## 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.
```rust
let hello_str = "hello";
// `hello_str` variable is the owner of the heap segment storing value `hello`
```
### Ownership transferring
When ownership is transferred or moved, the original variable becomes invalid and unusable. Variable assignment and parameter passing would trigger ownership transfer.
```rust
let hello_str = "hello";
let new_hello_str = hello_str;
// `new_hello_str` is now the owner, `hello_str` is no more usable
```
### 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.
```rust
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);
    
}
```
### 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.
```rust
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);
}
```

## 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
- [Ownership in Rust book
](https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html)
- [JVM Garbage Collector](https://www.baeldung.com/jvm-garbage-collectors)
-  [`new` and `delete` in C++](https://www.geeksforgeeks.org/new-and-delete-operators-in-cpp-for-dynamic-memory/)