Heaps and Stacks - explained like you're five
Chronicles of C++ Memory Management - Part 7
You know, there’s a Subreddit called “Explain Like I’m Five”, which is all about the idea that people ask complex questions and expect answers to be as simple as it was being explained to a five years old kiddo. And I find this to be really amazing. You can find all kinds of crazily interesting stuff like “Explain quantum physics like I’m five”, etc. It’s the art! It’s the damn absolute art of finding the proper explanation as if your listeners don’t own neither the super-complex vocabulary nor the patience to listen to long-form blabbing.
With that in mind, I’d like to discuss Heaps and Stacks in the most simple way possible. And I’d appreciate if you let me know how I did it!
As usual, the bite-sized infographic first and then the more detailed explanation below.
In all honesty, I was thinking about this A LOT. And when I say A LOT, I mean - for days on end. Maybe even a week. Trying to find the right single-worded description of what Heap and Stack represent. We all know the formal definitions and all, but what are the actual real-life examples.
I decided to go with a “Beach”. Beaches are usually big enough that you can “store” everything from a towel all the way to a car; possibly a helicopter as well. Beaches are also public, most of the time, meaning that anyone can find a free spot and put their stuff there. Finally, I presumed that mostly everyone has seen a beach at least once in their life, so the symbolism should be simple to digest.
There’s a downside to the “Beach” symbolics though. When you’re on a beach, everybody can see everybody else’s stuff. And Heaps are not like that. Heaps are still private to the process who asked for them; unless explicitly shared with others. So I was thinking about saying that “Heap is like a Private Beach”, but that posed some additional questions that I wasn’t willing to entertain (e.g. what does “private mean”? Who can access that beach then?).
I settled on the idea that “Heap is like a beach”. You can leave as many stuff as you want there (much more than on a Stack). Stuff remains there (almost) indefinetly (from the POV of running process, “indefinitely” means for as long as your process is running) and it can get fragmented, just like Heaps do. Whether I got it right is left to be answered by you - the reader :)
On the other hand, going with the “Beach” symbolism called for finding the right symbol for Stack. In contrast to the Heap, Stack is of limited size and everything gets wiped out the moment it goes out of scope.
I settled on the idea of “Hotel Room”. It’s way smaller than the beach (just like Stack is), it houses very limited set of stuff, but the moment you check-out (i.e. your data goes out of scope) everything gets wiped out and memory is “returned” back to the process. The moment you leave your room, the cleaning stuff knows that whatever is left there is not needed any more; just like with the Stack.
Whether I’m right or wrong, I leave for you to judge and let me know!
Back to the original story of Stack vs Heap, what seems to be rather interesting is that they are both just RAM memory after all! Hell, I’d even claim that Stack & Heap are more like implementation details of the language runtime! Neither C++ nor C standards say ANYTHING about Stack or Heap. They do discuss the life-time of the initialized variables (i.e. whether it’s scoped to current scope, or should it live for as long as your process lives) but there is NO mention of Stack or Heap. Go check it out if you don’t believe me.
Main difference which is actually is important is HOW are they allocated. And I blabbed about this in the past articles as well, but, the long story made short is - your thread gets its fixed-sized Stack once it starts the execution and that’s about it. You can consume that memory in any way that you want, but you can’t allocate “more Stack”. You CAN specify how much stack memory you need during the compilation time, but you CAN NOT increase the stack size at execution time. That’s where Heap jumps in.
On the other hand, Heap is dynamically allocated. As in - you ask for it, and if there is free RAM, you get what you asked for. Good news is that you can allocate as much as the OS can physically support. The bad thing is that if you make two separate allocations, you might end up getting fragmented memory, which is not ideal if you’re trying to squeeze out the max performance. But we’ll talk much more about that in future articles.
Finally, as someone coming from the Managed languages world (i.e. that nice place where someone else takes care of your memory), I really got used to the fact that “new” is there to instantiate objects and place them on the Heap. “new” was what you do to MAKE AN INSTANCE OF A CLASS. Ha ha, says C++ :)
As I mentioned in the previous article, when it comes to C++, “new” is there to allocate memory. USUALLY, this memory comes from the Heap. Yes. But this is NOT defined by C++ language at all! C++ says that “new” should instantiate objects whose lifetime should not be tied to the current scope. That’s about it! HOWEVER, and you can read this in that previous article I referenced above - you can totally override the behavior of “new” by defining your own “operator new” and allocating the memory from Stack, or maybe from an SSD drive :)
And that’d be all I had to share with you for today! Next time I’m going to discuss memory leaks and why do they happen and then make an honorable mention of pointers & references. After that I’m going to dig deeper into HeapAlloc and VirtualAlloc, which are Windows’ lowest level functions that you can call to allocate some memory. Until then, if you find this interesting and you haven’t subscribe yet, do consider doing so now :)
Thanks for reading and let me know how you liked this one!
Other stuff you might like: