Dynamic Memory and the Pitfalls of Manual Management

The Stack vs. The Heap

Where does memory live?

Until now, we've used the Stack for variables. It's fast and automatic, like your desk. But for flexible data—like a web browser with an unknown number of tabs—we need the Heap, a massive warehouse for memory.

To build truly flexible C++ programs, we must look beyond the Stack and understand the Heap. Think of the Stack as your desk: organized and fast, but small. The Heap is like a massive warehouse where you can request as much space as you need, but you're responsible for checking it back in. In the warehouse, when you request space, you get a receipt—this is your pointer. It holds the address of the space, but the manager won't clean it up for you. If you lose that receipt, that space is gone forever.

Manual Allocation: new and delete

Requesting and Releasing

We use the new keyword to allocate memory on the heap and delete to free it. This pairing is the golden rule of manual memory management.

Let's see this in code. When we call 'new int', the system finds space and returns its address. Notice how 'pNumber' now points to a block in the Heap. When we call 'delete', that block is freed, and we set the pointer to 'nullptr' to stay safe.

Building Dynamic Structures

The Linked List Node

Dynamic memory allows us to create structures that grow. A Linked List uses nodes where each node points to the next one in the Heap.

Here we have two nodes. The 'head' pointer points to the first node, which in turn points to the second. We can access the second node's data through the first. When cleaning up, we must delete the second node first. If we deleted the 'head' first, we would lose the address of the second node, causing a leak!

Pitfall 1: The Memory Leak

The 'Lost Receipt'

A Memory Leak occurs when you lose the pointer to heap memory before calling delete. That memory stays reserved but is unreachable.

Watch what happens when we reassign a pointer. We allocate space for the number 5, but then we immediately point to a new location for the number 10. The first block is now 'leaked'—it's still occupied, but we have no way to reach it or free it.

Pitfall 2 & 3: Dangling and Null

Ghosts and Nothings

A Dangling Pointer points to memory that's already been deleted. A Null Pointer Dereference happens when you try to look inside a pointer that points to nothing (nullptr).

A dangling pointer is like having a key to a house that's been demolished. You try to enter, and you fall into a hole. A null pointer dereference is even worse—it's trying to open a door that doesn't even exist. Both lead to crashes.

Interactive Diagnosis

Examine the code snippets and click on the line that contains a memory safety error.

Here is a function that processes data. It has a hidden danger. Can you find the line that causes a problem? Not quite. That line is safe. Look for a place where memory is allocated but potentially never released. Exactly! By returning early without calling delete, we've created a memory leak. Every path through your function must ensure memory is freed.

The Debugging Challenge

Spot the Double-Trouble

Read the code below. There are two major issues. Write a brief diagnosis explaining what is wrong and how to fix it.

Look closely at this 'processData' function. It allocates an array but handles errors poorly. Type your diagnosis in the box.