For a while, I have been lazily picking up the Rust programming language! Despite being a gopher, I’ve always admired Rust from afar. I started learning about it a month and a half ago! I started out reading THE BOOK — by the rust team and solving Excersim exercises whenever I could afford the time. For the past two weeks, I’ve been on chapter 4 of The Book — Understanding Ownership! Ownership is a core concept in Rust, kinda tricky to grasp, although that wasn’t the only reason I’d been stuck for the past two weeks, my time had been constrained.
I decided to spend some time this weekend, finishing up that chapter and getting a grasp of certain concepts around Ownership in rust and I did. I made notes in the process and decided to publish them for my future self who I believe in a couple of months would be proficient in Rust & would /cringe/ reading this piece. I do not intend for this post to be a tutorial, but rather my notes on a new concept I am learning. The aim is not for you to learn anything from this post, but I would be glad if you did.
-
When a data type of say type String is created, because its size is unknown at compile-time, space has to be allocated for it on the heap.
-
The memory allocator returns a pointer, this pointer which is the address of the allocated heap space is stored on the stack[alongside other values like capacity & length in the case of String datatype]!
let x = 1;
let y = x;
-
In the above snippet, we create a variable y, give it a value of 1; create a variable y and give it a value of x — the same variable we created in the line above.
-
The above assignment works fine since the size of the data type is known.
-
Assigning variable y to the value of x( for unknown size-types) doesn’t quite behave as expected!
-
Assigning the values does not make a copy of the value on the heap(It would be expensive for rust). Because the heap data is not copied x & y would be duplicated on the stack but point to the exact same heap data.
-
This would cause a problem when both x & y try to free the memory when they go out of scope! They both would try to free up the same heap of data leading to a double free error.
-
Doubly freeing memory allows for security vulnerabilities in programs such as the write-what-where condition where bad agents could write an arbitrary value to an arbitrary location!
-
To solve this problem, Rust invalidates the variable once it has been “copied”.
let x = String::from("hello");
let y = x;
// x is not valid anymore.
-
If x defines a value & y is assigned to x, x is moved to y and x is invalidated.
-
The concept of “moving” in Rust is similar to shallow copying in some languages, the main difference being that the parent variable was invalidated.
-
Trying to use the invalidated variable would result in an error as seen below.
-
After the Move, since a variable has been invalidated, The double-free error is prevented.
Looking forward to exploring more of Rust!