DEV Community

Cover image for Stack vs Heap Memory: What Actually Happens When You Create a Variable?
Aditya Sharma
Aditya Sharma

Posted on

Stack vs Heap Memory: What Actually Happens When You Create a Variable?

Look at this line:

int x = 10;
Enter fullscreen mode Exit fullscreen mode

What actually happens when the program executes it? Somewhere in memory, space for an integer gets set aside, and the value 10 goes into it. But where in memory? And what decides when that space gets reclaimed?

The answer involves two different regions of memory that programs use for different purposes.

Program
   ↓
Memory
   ├── Stack
   └── Heap
Enter fullscreen mode Exit fullscreen mode

The Stack

When your program calls a function, the runtime needs somewhere to put things: the function's local variables, the arguments passed to it, a record of where to return when the function finishes. All of this gets stored in a structure called a stack frame, and that frame lives on the stack.

void example() {
    int x = 10;
}
Enter fullscreen mode Exit fullscreen mode

When example() is called, a frame is pushed onto the stack. x lives inside that frame. When example() returns, the frame is popped. The memory that held x is gone, or more precisely, it's considered free to be reused. You don't have to do anything to make that happen. The lifetime of x is tied to the lifetime of the function call.

This is why local variables work the way they do. They exist while the function is running and disappear when it's done. The stack grows and shrinks as functions are called and return, and the bookkeeping is simple: the runtime just maintains a pointer to the current top of the stack.

Allocation on the stack is cheap for this reason. Reserving space for a local variable is typically just adjusting that stack pointer by a fixed amount. No searching, no tracking, no negotiation with the operating system. The frame is there when you enter the function and gone when you leave.


The Heap

Some memory needs to outlive the function that created it. Maybe you're building a data structure that gets passed around. Maybe you don't know at compile time how much memory you'll need. The stack isn't designed for this. That's what the heap is for.

int *p = malloc(sizeof(int));
*p = 10;
Enter fullscreen mode Exit fullscreen mode

malloc allocates memory on the heap and returns a pointer to it. That memory doesn't disappear when the current function returns. It persists until someone explicitly frees it, or in languages with garbage collection, until the runtime determines it's no longer reachable.

The pointer p itself might live on the stack. But what p points to lives on the heap. That distinction matters:

stack
┌──────────────┐
│      p  ──────────────┐
└──────────────┘        │
                        ↓
                      heap
                ┌───────────────┐
                │  int value    │
                └───────────────┘
Enter fullscreen mode Exit fullscreen mode

This is a useful mental model, but treat it as conceptual. Different languages and runtimes manage this differently. The diagram is showing you the idea, not a literal memory map.

The tradeoff with heap allocation is that it's more work. The runtime has to find a suitable free region, track what's in use, and eventually reclaim memory when it's no longer needed. In C, you do that manually with free(). In Java or JavaScript, a garbage collector handles it. Either way, there's overhead that stack allocation doesn't have.


Why Both Exist

The stack is well-suited to local execution state: things that exist for the duration of a function call and nothing longer. Its automatic lifetime management is a feature, not a limitation.

The heap is well-suited to data with more flexible lifetimes: things that need to outlive the function that created them, or that need to be shared across different parts of a program, or whose size isn't known until runtime.

Most programs use both constantly. A function's local variables live on the stack. Objects created with new in Java, or allocated with malloc in C, live on the heap. References or pointers on the stack point into the heap.


Common Misconceptions

A few things that get oversimplified.

Not every local variable is guaranteed to live on the stack. Modern compilers can perform escape analysis: if they determine that a local variable doesn't escape the current function, they might keep it in a register rather than pushing it to memory at all. Conversely, if a variable does escape, the compiler might allocate it on the heap even if you wrote it as a local. The source code doesn't dictate the physical layout; the compiler and runtime do.

Not every object is guaranteed to live on the heap. Some languages and runtimes can allocate short-lived objects on the stack if they can prove it's safe. The distinction in source code between "stack variable" and "heap object" doesn't always map cleanly onto what actually happens.

Stack is not simply "fast" and heap is not simply "slow." Stack allocation is simpler, but whether that translates to a meaningful performance difference depends entirely on the workload. The more important factor for memory performance is usually cache behaviour, and that has more to do with access patterns than with which region the memory lives in. The stack is not the same thing as CPU cache.

Heap allocation doesn't necessarily mean the program talks to the operating system every time. Memory allocators like malloc typically request larger chunks of memory from the OS and then manage those chunks internally. Individual malloc calls usually don't cross the kernel boundary; they're served from a pool the allocator already has.


The mental model worth keeping:

Stack → function calls, local execution state, automatic lifetime
Heap  → dynamically managed memory with more flexible lifetime
Enter fullscreen mode Exit fullscreen mode

These are useful conceptual categories. Where memory physically ends up, and how fast it is to access, depends on the language, the compiler, the runtime, and what the hardware decides to do with it. The stack and heap are real, but they're not rigid physical rules. They're a model for thinking about how programs manage memory, and like most models, they're most useful when you also know where they break down.

Top comments (0)