stack · main()heap (free store)int* pint* a0x5a100x5a300x5a340x5a381#include <iostream>2int main() {3 int* p = new int(42);4 *p = *p + 1;5 int* a = new int[3]{1, 2, 3};6 std::cout << *p + a[2] << '\n';7 delete p;8 delete[] a;9}!!new0x5a10*pnew[]0x5a30433deletedelete[]
Violet card: the program (heap.cpp); a highlighted line is the one runningBlue cells: the pointers p and a on the stack; khaki cells: ints on the heap (faint = not reserved)Arrows: where a pointer points (red = dangling); tokens: new, addresses, values, deleteIn front: the source card heap.cpp and the output block. At the back: main's stack frame with the pointers p and a, and the heap with room for one int and a three-int array. new takes memory from the heap and returns its address, which the pointer on the stack keeps; the arrow shows where it points. delete gives the memory back, and the pointer is left dangling (red). At the closing brace the stack cleans itself up; the heap is only cleaned by your deletes. Without them the memory leaks. The addresses 0x5a10 and 0x5a30 are made up and short so they fit. Real ones are longer (for example 0x55d4c3a1b2c0 on 64-bit Linux), change from run to run, and blocks usually have gaps and bookkeeping bytes between them.

Two places

  1. A local variable lives on the stack and disappears when its function returns. The heap is a big pool of memory you ask for while the program runs. What you take stays yours until you give it back.

Asking with new

Giving it back

What happens

;; step 1/9 · two-places
stack   local variables of the running functions
        made and removed automatically, in order
heap    (the standard says: free store)
        you ask:     new     → it gives memory
        you return:  delete  → it takes it back
        lives as long as you decide, not one function call

The addresses 0x5a10 and 0x5a30 are made up and short so they fit. Real ones are longer (for example 0x55d4c3a1b2c0 on 64-bit Linux), change from run to run, and blocks usually have gaps and bookkeeping bytes between them. An int is 4 bytes on the usual desktop platforms (64-bit Linux, macOS and Windows), which is why a[1] sits 4 bytes after a[0]. The standard only promises at least 16 bits.