Stack Vs. Heap

Salah Besbes
5 min readOct 18, 2020

--

Stack:

The stack is a special region of your computer’s memory that stores temporary variables created by each function. it’s the memory set aside as scratch (available) space for a *thread of execution. When a function is called, a block is reserved on the top of the stack for local variables and some bookkeeping data. When that function returns, the block becomes unused and can be used the next time a function is called. The stack is always reserved in a LIFO (last in first out) order; the most recently reserved block is always the next block to be freed.

thread: A multithread program contains two or more parts that can run concurrently. Each part of such a program is called a thread, and each thread defines a separate path of execution.

1. stack behavior

A key to understanding the stack is the notion that when a function exits, all of its variables are popped off of the stack (and hence lost forever). Thus stack variables are local in nature.

Notes:

  • the stack grows and shrinks as functions push and pop local variables
  • there is no need to manage the memory yourself, variables are allocated and freed automatically
  • the stack has size limits
  • stack variables only exist while the function that created them, is running

Heap:

The heap is a region of your computer’s memory that is not managed automatically. it’s a memory set aside for dynamic allocation. It is an area of memory where chunks are allocated to store certain kinds of data objects. Unlike the stack, there’s no enforced pattern to the allocation and deallocation of blocks from the heap, you can allocate a block at any time and free it at any time. This makes it much more complex to keep track of which parts of the heap are allocated or free at any given time.

2. heap behavior

objects are always created in heap space and the references to this objects are stored in stack memory.

The memory managed by the heap may be allocated to the program from anyplace in the heap, even if that memory is in the middle of the heap.

Each thread gets a stack, while there’s typically only one heap for the application.

The stack is attached to a thread, so when the thread exits the stack is reclaimed. The heap is typically allocated at application startup by the runtime, and is reclaimed when the application (technically process) exits.

Unlike stack, a heap isn’t threadsafe and needs to be guarded by properly synchronizing the code.

What happen when we execute this code?

when we execute out program, we just create our first stack frame it contain all the data and variables in it . a Frame is the collection of all data on the stack associated with one subprogram call.
Next when we call putchar _recursive(“holberton”), we check for the Null Terminator and write the first char “H”, we pass the next address to putchar _recursive(str + 1) -> putchar _recursive(“olberton”). by doing that we create an other frame in the same stack just on the top of the old one. we push onto the stack.

same thing happen when we call it again, we check , we write *str, we advance the dress by one, we pass it into the same function (because it’s recursive) and we create an other frame on the top of the last one in the same stack … and the stack keep being filled.

Stack pointer is register that holds the adress of the last frame on the stack . Every time we create a new frame the stack pointer moves into it, and get incremented. Until we found the Null terminator than we stop (exit the recursive function), we pop off stack frames in the last-in-first-out manner until we reach out return(0) logic in the int main(void) function in our first stack frame.

what happen when we don’t stop ?

Well, if we don’t stop we are stack in an infinite loop, the function keep calling it self, and frames keep adding on each other. until what ???
until there is no more free memory in the stack of this program.

ulimit -s or -a (to see all limits)
$ 8192 kbytes => 8.192 mbytes

In fact the stack is a part of the virtual memory shared with the heap. If we don’t stop the stack keeps growing against the heap (moving the stack pointer upward on each call) until we reach the maximum size allocated 8192 kbytes. Then error “Stack over Flow” appear.

So to resume our main function has a constant memory size into the stack fixed by the operating system (before even we compile it) that we cant cross. So when developers write programs they have to consider how much memory (bytes) they are using, and where to put it.

In the other hand, the heap is the segment of memory that is not set to a constant size before compilation .

Think of the heap as a “free pool” of memory you can use when running your application. The size of the heap for an application is determined by the physical constraints of your RAM (Random access memory) and is generally much larger in size than the stack.

We use malloc(), calloc(), realloc() to allocate memory in the heap and free() to release it.

So when we use heap ??

  • When we don’t know exactly how much memory we want to allocate
  • When we know that we gonna exceed the stack size available
  • when we need a variable to last till the end of your function or program

What happen if we don’t release the memory allocated in the heap??

If you don’t release the memory using the free() function before ending the program, we have memory leak. If your application has enough memory leaks, it can consume more memory than is physically available and can cause programs to crash.

For how long the memory leak persist?

The memory leak lasts until the system is reset. When power turn on again the program restart and all the memory would be available again.

--

--