Where Values Live: Memory, Stack, and Heap
So far we have talked about programs as text. But the moment a program runs, it needs somewhere to keep the values it is working with. That place is memory: a vast row of numbered slots the running program can write to and read from at blinding speed.
Picture an endless wall of small lockers, each with a number on the door. Storing a value means putting it in a locker and remembering the number. Reading it means going back to that number. The program does this millions of times per second without ever losing track.
Watch variables come to life
Step through the little program below and keep your eye on the variables table. Each assignment brings a name into existence with a value. That table is a live, honest picture of the program's memory as it runs.
Two regions, two jobs: the stack and the heap
Real programs organize memory into two main working regions. The stack is tidy and automatic: every time a function is called, a fresh frame of space for its local variables is stacked on top, and when the function returns, that frame is thrown away. The heap is the open floor: space requested on demand for things that must outlive a single function call, like a list that keeps growing or text built at runtime.
The stack is fast precisely because it is disciplined: allocation is just moving a pointer, and everything about a call's local state has a predictable position relative to its frame. The heap trades that discipline for freedom, which is why languages either make you manage it by hand or run a garbage collector to reclaim heap space nobody references anymore. All seven Level 1 languages are garbage collected.
One further detail that pays off in the reverse engineering lessons: memory is recycled, not erased. When a stack frame is popped or the collector frees a heap object, the bytes usually stay in place until something else overwrites them, and a moving collector can leave several stale copies of the same value behind. In practice a value's lifetime in memory is longer than its lifetime in your program, which widens the window in which an inspection of memory can still capture it.
Why memory matters for code protection
Here is the thread that runs from this lesson all the way to the end of the academy. Whatever a program computes exists in memory while it computes it. Decoded text, checked passwords, decrypted values: at the moment of use, the real thing is sitting in a numbered slot, in the clear.
Obfuscation transforms the text of a program. It cannot transform what the program must eventually hold in memory to do its job. When Level 5 shows you attackers dumping memory from a running program, this lesson is why that attack exists.
Summary: a running program keeps every live value in memory, with the stack holding tidy per-call state and the heap holding everything longer-lived. Whatever a program uses must exist there, in the clear, at the moment of use. Transforming the text of a program cannot change that, and honest protection is designed with this limit in view.
Frequently asked questions
Do I need to manage memory myself?
Not in the languages this academy focuses on. Lua, JavaScript, Python, Go, Java, Ruby, and PHP all reclaim unused memory automatically with a garbage collector. Understanding the stack and heap still pays off, because it explains both performance and where data physically lives.
Is the variables table in the visualizer showing real memory?
It shows the teaching interpreter's variable store, which is the same idea one level up: names mapped to current values, updated as each statement runs. Real machines add addresses and bytes underneath, but the picture you build here transfers directly.