Stack and Heap refer to different memory segments. In general, the size of the stack will be much smaller than the heap, but the time required to access data on the stack will be much shorter than trying to access data that is stored in the heap.
This is an inherently confusing question. Why? Because in computer science there is a data structure called a “Stack” and a data structure called a “Heap.” When people are talking about the stack and the heap and computer memory, they are NOT referring to the data structures, but to memory segments inside the computer. To make it more confusing, the “stack” they are talking about actually employs the “Stack” data structure. For that reason, we will really quickly describe what a “Stack” data structure is before we investigate what people mean when they refer to the stack vs the heap.
A Stack is merely a way to sort data. The easiest way to think of it is to imagine stacks of things in the real world — like plates, for example.
So what can you do with these “stack of plates” data type? Well, in Computer Science there are three things you can do to stack:
When you add something to a stack it is called a “push.” It is the only way to add items to the stack data structure. And each time you add an item it must be placed at the top of the stack. Just as though you were stacking plates, each new plate would be stacked on the others. You are not allowed to insert a piece of data into the middle of a stack.
When you remove something from a stack it is called “popping” the item off the stack. Just like with pushing things to a stack, there is a rule that tells you that you are only allowed to take the item at the very top of the stack. Again going back to our stack of plates: if you want a plate you must take whatever plate is on the top of the stack. You cannot take a plate from the middle of the stack.
Peek is the ability to look at the item that is currently at the top of plates. Pretty simple (to beat a dead horse), going back to our plate example, the only plate you can really examine is the plate at the top of the stack.
Now that you understand how a stack data structure works we can proceed to explaining how these different memory segments are used. At it’s foundation all computing can be roughly broken into three categories. You have the program, which is a set of instructions. You have the processor, which receives those instructions and executes them. Then you have the memory, which stores the results of the execution.
Like I said before, when talking about Stack vs Heap we are talking memory segments, so let’s investigate the “Memory” part of this diagram a little closer.
If you remember from before, the stack section of memory actually uses the rules of a stack data structure. But since this function is so low level, it has to keep track of the stacks status itself. So in the first slot in the stack, memory is reserved for a variable called a stack pointer. This is in charge of keeping track of where the “top” of the stack is. Going back to our plate illustration, the stack pointer points to the position right above the top plate. That way, if you want to add a plate to the stack you know what position it needs to be added at. This data structure allows us to do everything that we do with computers today. Lets look at the following code and the way that it would be stored on the stack and the heap.
x = 1 + 2;
This code would result in instructions similar to this:
- Push the value 0 to the stack to represent ‘x’
- Push the value 1 to the stack
- Push the value 2 to the stack
- Call the Addition Function
- Set the value of ‘x’ to the result of the function
What’s interesting about these instructions is that if you look close enough, you can see the main stack in action. Let’s visualize this process.
Step 1: Push the value 0 to the stack to represent ‘x’:
Step 2: Push the value 1 to the stack :
Step 3: Push the value 2 to the stack:
Step 4: Call the addition function :
This is the first interesting step that needs explanation. So in order for the function that handles addition to work, it needs two values to add. Where does it get those values? It pops them off the stack. So when the function is called, it will ‘Pop’ 2 and then 1 from the stack. It will then add them together and ‘Push’ the result back to the stack. After which the stack will look something like this:
Step 5: Set x to the result:
To achieve this, the ‘3’ is popped from the stack and placed in a local register. The ‘0’ is then popped from the stack and set as the current variable, and then it has the value 3 written to it. What you will notice is that this leaves us with an empty stack. As it turns out, all programs have to be written in a way where the stack is emptied at some point, or else you will run into the infamous “Stack Overflow Error” which is where the name for the popular computer science website came from.
So now that we know what the stack is used for we can answer what the heap is used for. Since the stack has more conservative size restrictions, it is common to store larger objects in the heap instead of the stack. Now what objects exactly get stored where is decided by the particular operating system that you are running. The most common thing to be stored on the heap are objects and arrays. To keep this conversation programming language agnostic, I will refer to these objects in the most general of terms. The easiest way to imagine an object is a box that holds values. It is important to note that the computer has no idea what an object is; objects are just things that humans use to help us write programs. Let’s imagine we created the following object:
As you can see, this object is very simple. It contains three number values. This is an example of an object that could be stored on the heap. The OS (operating system) would see that the object has three values, so it would allocate three slots in memory to store the object. The OS then pushes the address for the first memory slot of the object. This address is commonly referred to as a pointer, because it points to the address where the data is being stored. It would end up looking something like this:
So if we were to create a new object with the values 25, 37, 98 it would look like this:
What does that allow us to do? Well, now the stack only has to store the pointer value of ‘80001,’ instead of all three values (25,37,98). This helps to reduce the memory requirements of the stack. The pointer value at this point acts as a kind of bookmark that we can use to quickly navigate back to a particular section of memory and read values we stored there. Whereas this might not seem to be very important in the above example, you can imagine how handy this would be when storing large arrays or objects with many properties attached to them.