When it comes to memory management, what does it mean that our data are stored on the stack? What are the advantages and disadvantages of using the stack?
The stack allows for the rust compiler to add and remove functions and business logic in a specific order. It means that given a set of rules, the program developer is able to reliably dictate how the story goes within the program. If there was no stack and functions and declarations were fired at random, there would be output inconsistencies and errors all over the place. In short, we’d be dealing with unprecedented levels of bedlam.
For example, let’s say a variable has been declared, that is used in a function:
fn main() {
let a: u8 = 2;
printa(a)
println!("Let's print a again: {}", a);
}
fn printa(x: u8) {
println!("Let's print a: {}", x);
let b: u8 = 4;
}
In this example , the a
variable is added to the stack, and then it hits the printa
function, where the printa
function is added to the stack, where it goes through the function from top to bottom. Once the last line of the function has been executed, the memory allocated for the function (and the b
variable) is removed from the stack, and can continue with the println!("Let's print a again: {}", a);
execution. This is a logical set of steps, and the programmer has control over the order in which declarations and methods are processed. It also means that the program no longer has to allocate memory for b
after the printa
function is removed from the stack.
When it comes to the stack and efficiently managing memory, it is important to note that when a new function is added to the stack, it does not have access to variables outside of what is provided as arguments. This means that the compiler will spit an error if a function calls for a variable and there are no arguments passed, for example:
fn main() {
let a: u8 = 2;
printa()
println!("Let's print a again: {}", a);
}
fn printa() {
println!("Let's print a: {}", a);
}
In the example here, a
will be unrecognised in the printa
function, because it has been added to the stack, and it has no access to variables from below in the stack. Even though a has been declared in the program, the printa
function is a new layer on the stack to the main
function, and therefore scoping is limited to what is provided within its scope.
The main benefit is that the developer is able to produce super efficient programs which only use the memory which is required for any given call added to the stack. Many developers enjoy the ability to have control over what and when is allocated to memory.
It does however, mean that the developer must be more conscious of what variables are available within the stack, with the help of the compiler. It also means that elements which are stored within the memory can take more time to add and remove.
TDLR:
Advantages: Less/no wasted memory.
Disadvantages: More effort to create and remove elements used within the program… And more headaches trying to please the compiler
A really great analogy for understanding the stack (and some other rust concepts) is at this video.
When it comes to memory management, what does it mean that our data are stored on the heap? What are the advantages and disadvantages of using the heap?
The heap allows for global storage for variables. This means that memory allocation can be stored dynamically, and is much less strict than the stack. The heap could be referred to as a free-floating region of memory which is always available.
When looking at a stack, you can visualise it by standing above a stack of papers, and only being able to read what is on the top page.
When looking at a heap, visualise sitting next to a heap of pages sitting on top of each other - you can see all of the sheets, but you can’t read anything directly… but if you want to read something, you can pull the sheet (variable) out that you require and read it, because you can see it. It will just take a little bit more time to pull the sheet out, and put it back in the heap - as opposed to the stack where you can instantly read what’s available on the top of the stack (although nothing below it).
The advantage of using the heap is that the programmer is able to be more loosey goosey with their code, knowing well that the program will happily draw from the heap. Making variables and using them in functions is more simple and streamlined.
The main disadvantage of this is that programs will generally become inefficient, and especially more so as the program grows in size. The lack of control means that variables will always be available to draw from in storage.