Skip to Content
Course content

43: Stack vs Heap in C++

Click on the "Edit" button in the top corner of the screen to edit your slide content.

I want to show you something that trips up almost every C++ developer at some point. It’s the moment you realize that int x = 10; isn't just "putting a number in memory," but is actually making a very specific choice about where that memory lives.

Where did my data go?

Let's start with a common mistake. Suppose we're building a simple system to generate a player's welcome message. I'll write a function that creates a string (using a C-style char array for clarity here) and returns it to the caller.

char* getWelcomeMessage() {
    char message[] = "Welcome to the Arena, Warrior!";
    return message; 
}

int main() {
    char* msg = getWelcomeMessage();
    std::cout << msg << std::endl;
    return 0;
}

If you run this, you might get lucky and see the message, or you'll see a string of random gibberish, or the program will simply crash. Why? The code looks logically sound. But here is what's happening under the hood: message is a local variable. It lives on the stack.

The stack is incredibly fast because it works like a pile of trays. When getWelcomeMessage is called, a "frame" is pushed onto the stack containing our array. The moment the function returns, that frame is popped off. It's gone. I've returned a pointer to a memory address that the CPU now considers "empty" or available for the next function call. I'm pointing to a ghost.

Hitting the ceiling

Now, you might think, "Fine, I'll just make my stack variables bigger." Let's try that. Imagine we're loading a massive game map—just a huge array of integers representing terrain heights.

void loadMap() {
    int mapData[1000000]; // A massive array on the stack
    mapData[0] = 1;
    std::cout << "Map loaded!" << std::endl;
}

int main() {
    loadMap();
    return 0;
}

Depending on your OS and compiler settings, this will likely trigger a Stack Overflow. Not the website, but the actual error. The stack is small—usually only a few megabytes. When I try to shove a multi-megabyte array onto it, I run out of room immediately.

This is where we have to change our strategy. We need the heap.

Taking a walk in the wilderness

The heap is a giant pool of memory. Unlike the stack, it doesn't automatically clean up after you. You have to explicitly ask for a piece of it and, more importantly, explicitly give it back. Let's rewrite that map loader using the new keyword.

void loadMap() {
    // This doesn't put the array on the stack; 
    // it puts a small pointer on the stack that points to a big array on the heap.
    int* mapData = new int[1000000]; 
    
    mapData[0] = 1;
    std::cout << "Map loaded successfully on the heap!" << std::endl;

    // If I stop here, I've just created a memory leak.
    delete[] mapData; 
}

Notice the difference. The int* mapData variable itself is still on the stack (it's just a memory address, so it's tiny), but the 1,000,000 integers are sitting over on the heap. Because they are on the heap, they stay there until I call delete[].

This also solves our first problem. If I wanted getWelcomeMessage to actually work, I would use new char[...]. The memory wouldn't vanish when the function ended; it would persist until the main function explicitly deleted it.

The Trade-off

So why not put everything on the heap? Because the heap is slower to allocate and, as I just demonstrated, it's dangerous. If you new something and forget to delete it, your program will slowly eat more and more RAM until the OS kills it. The stack is "automatic"—it's safe, fast, and cleans up after itself. The heap is "manual"—it's flexible and huge, but requires a disciplined programmer.




📋 Practical Task

Exercise: Building a Dynamic High-Score Registry

You are tasked with creating a high-score system for a game. Since you don't know how many players will join the game at runtime, you cannot use a fixed-size stack array.

Write a program that does the following:

  1. Asks the user how many high scores they want to enter.
  2. Uses the new keyword to allocate an integer array on the heap based on that user input.
  3. Populates the array with scores provided by the user.
  4. Calculates and prints the average score.
  5. Crucially: Properly cleans up the allocated memory using delete[] to ensure there are no memory leaks.
Rating
0 0

There are no comments for now.

to be the first to leave a comment.