For the complete documentation index, see llms.txt. This page is also available as Markdown.

🐸Memory Model

Memory Layout

Variables can either be created or destroyed. They can also exists on different locations (i.e the stack, heap or static storage)

Stack vs Heap

Stack

Variables created (i.e allocated) on the stack possess automatic storage duration. This means they are:

  • allocated when execution enters their scope

  • deallocated when out of scope

Why is stack allocation fast?

Allocating (and deallocating) variables on the stack is fast as it mainly involves incrementing (and decrementing) the stack pointer.

This is also the reason why uninitialized variables on the stack possess garbage values because the memory they occupy is not automatically zeroed.

To jog your memory, all the previous variable declarations in Variables and Pointers were all allocated on the stack.

Consider the following example (please ignore the implementation details of Person class for now)

The following output is as shown:

Observe that similar to the Last-In-First-Out (LIFO) behaviour of literal stack data structure, objects are constructed in order of declaration. They are also destroyed in order of reverse order.

Note that the behaviour is tied to scope, objects are destroyed as soon as it exits the scope.

Code
Output

Heap

While the stack is fast, it does suffer from a few limitations:

  • Size of the objects must be known / determinable at compile time

  • The lifetime of objects is tied to scope

⚠️ More about the limitation

Consider the following code snippet:

It appears to work when we try running with clang++ main.cpp -o hello-world

But look what happens when I try to run with stricter flags: clang++ -std=c++17 -Wall -Wextra -pedantic-errors main.cpp

This is because VLA (Variable-Length Arrays) are actually not part of standard C++. Indeed, the size of arrays must be known at compile-time.

Following the above school of thought, why does the below code still not work? 🤔

You can use a new keyword to allocate memory on the heap. Unlike the stack, the heap memory is not tied to scope. It persists until it is explictly deallocated with delete.

Let's take a look at how heap tackles these limitations:

⚠️ Spot the error in the above code snippet

We've just encountered a common pitfall of allocating variables on the heap. The above code snippet is plagued by a memory leak.

The memory allocated using new is never deallocated using delete . This means the allocated memory remains reserved after after it's no longer needed.

We can fix the code by appending delete[] arr; to the back of the program like so:

Dangling Pointers

Another common pitfall that programmers often stumble upon is the issue of dangling pointers. This refers to the situation when we try to access memory that already has been deallocated.

The above is an example of undefined behavior. For me, it prints 0 but the C++ standard makes no guarantees about what happens.

It could also potentially print 5, print garbage values or crash through a segmentation fault.

Last updated

Was this helpful?