Ownership Simplified

Ownership Simplified

Rust guarantees memory safety with a feature called Ownership.

Memory Safety

This is a property of a program where memory pointers used always point to the valid memory which stops programmers from introducing specific types of bugs related to memory. One of the examples that can cause memory safety issues is Dangling pointers(pointers that point to invalid data (or) null). For languages which don't have a garbage collector developer needs to explicitly allocate and free the memory. But rust handles memory safety by ownership model.

The ownership model consists of a set of rules that the compiler needs to check at compile time. If ownership rules are violated compiler won't compile the program. Whenever a variable goes out of scope, memory is freed based on the ownership model.

Example:

fn main() {
    let y = 6; 
    {
    let x = y+1; //local variable x
    println!("{}",x)
    } // x goes out of scope here and the compiler frees memory 
    println!("{}",y)
}

The Stack and The Heap

Both of them are memory segments that are available for a program to use at runtime. As rust is a systems programming language it is better to know how values are stored in stack and heap.

Stack

Stack stores variables of fixed size at compile time. Memory management in stack follows the Last In First Out order.

Consider an example

Think of a stack of plates: when you add more plates, you put them on top of the pile, and when you need a plate, you take one off the top. Adding or removing plates from the middle or bottom wouldn’t work as well! Adding data is called pushing onto the stack, and removing data is called popping off the stack.

Programming operations on the stack is faster because of fixed size and direct access.

Heap

Memory management in heap is distinct compared to stack and is less organised. Data with an unknown size at compile time or size that might change must be stored on the heap. The size of the values being stored on the heap is unknown.

When we put data on the heap, we request a certain amount of space. The memory allocator finds the space in the heap which is quite big enough, marks it as being used and returns a pointer.

Accessing data in the heap is slower and even requires bookkeeping(what part of the code uses what data, deduplicating data, cleaning up unused data).

Rust Ownership Rules

  • Each Value in Rust has an owner.
  • There can only be one owner at a time.
  • When the owner goes out of the scope, the value will be dropped.

Variable Scope

A scope is a range within a program for which an item is valid.

fn main() {
    let y = 6; 
    {
    let x = y+1; //local variable x
    println!("{}",x)
    } // x goes out of scope here and the compiler frees memory 
    println!("{}",y)
}

In the above snippet, the variable x refers to an integer. This variable is valid till the current scope of that variable ends.

In other words:

  • The variable x is valid when it comes to scope
  • It remains valid until it goes out of the scope.

Summary

In this post, we learnt about Memory Safety, How are the data stored in the heap and the stack and a brief introduction to the Rust Ownership model. Rust handles memory safety by using the ownership model. If ownership rules are profaned compiler won't compile the program. In the next post, we will focus on Memory and Allocation, Reference and Borrowing. If you have any doubts about the content in this post feel free to leave a comment so that I can address that and create the content clearer.

Did you find this article valuable?

Support The Missing Semicolon by becoming a sponsor. Any amount is appreciated!