Stack and Heap Allocation in Cpp

In cpp, memory you need to worry about sizes of data types and variables for arrays, it is way easier then people think, but does require some basic knowledge of stack and heap allocation and the difference. In most (probably all) programming languages, there exists a stack and a heap.

Comparison of the stack and the heap

The Stack

The stack is a predefined block of memory where variables store there data.

Allocating memory on the stack is super fast, since a block of memory is already reserved for this purpose.

Stack allocated variables look like regular variables, e.g.

// primitive data types
int a = 3;
float b = 3.0;
double c = 3.0;
char c = 'a';

// stack allocated arrays
int[5] arr = { 1, 2, 3, 4, 5 };

// classes and objects on the stack
obj o;

// with constructor
obj o(a);

Copying stack allocated variables you pass all the contents of a variable to the other variable.

Copying looks like

int b = 10;
int a = b;

You can also pass the location of a variable to a variable that points to it, to get the memory address you use &, and to show a variable points to an existing memory address you use *

e.g.

int b = 10;
int* a = &b;

When the variable falls out of scope, the variable is removed (popped) from the stack.

Stack allocated variables should be the norm, and use them whenever you can.

The Heap

The heap is a place where you can allocate memory at runtime when the sizes of data is not known.

Allocating memory on the heap is a more expensive process, since you need to allocate a block of memory for the variable to be stored.

Heap allocated variables are pointers that point to a location in memory, and is distinguished by the new keyword.

e.g.

// primitives
int* a = new 10;
float b = new 3.0;
double c = new 2.0;

// heap allocated arrays
int* arr = new {1, 2, 3, 4, 5};
int* arr = new int[5];

// classes and objects on the heap
obj* o = new obj();

// with constructor values
obj* o = new obj(a);

Copying heap allocated variable copies the location of the memory on the heap, but does not copy the values (similar to copying objects in Java).

e.g.

int* b = new 10;
int* a = b;

Note that when a heap allocated variable falls out of scope, it does not get removed from the heap. Instead we need to manually delete the memory from the heap.

// for normal pointers

// first make pointer null
b = null_ptr;

// second free memory
delete b;

// for arrays
delete [] arr;

Now when the variable falls out of scope, it no longer exists within the program.

Note that heap allocation is useful for when you do not know the size of something at runtime, say we need to create a dynamically sized array. Here dynamic means that the size is decided at runtime.

when you call the new keyword, the program needs to know the how much memory you need to allocate on the heap. Therefore the new keyword is different for arrays. When you call new what it is doing is allocating memory that is the size of your data type. The reason that it is good for arrays is that when you don't know the size of your array at compile time it allows you to create a block in the heap for that array.

When you create an array it allocates the size of your array * the size of your data type, hence why array you need to include how big an array is when you call new for an array.