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.