Stack Memory
The stack size is limited by the OS and is not designed to hold huge arrays.
The size of statically allocated variables is calculated at compile time.
The variable sizes must thus be known in advance (with the exception of VLA).
double arr[20];
#define n_max 20
...
double arr[n_max];
const double n_max 20;
...
double arr[n_max];
Heap Memory
Dynamically allocated variables can change size during runtime.
The are usually created by requesting memory using the new
keyword:
int *ptr;
ptr = new int[n];
How does this work?
You can think of the heap as a pool of memory that we can take memory from
and importantly give memory back to (when we do not need it anymore).
If we do not need the memory anymore we need to delete it:
delete[] ptr;
otherwise we end up with memory leaks.
The size of the heap is limited by your physical hardware.
Once the RAM runs out the heap may start accessing memory on the Hard Disk
which may become extremely slow.
Variable Length Arrays (VLA)
Warning: this is an explanation "why not to use this"!
Is a feature of C98 that allows to write arrays that have a variable length:
void foo(int n) {
int arr[n];
}
But it is not implemented by C++ and only a gcc extension so it may lead to a compile error on many compilers.
The reason that it is not supported is, that there are some problems that can arise with it.
In particular there exist no requirement whether an array has to be allocated
on the stack or on the heap and is thus implementation/compiler dependent.
Sidenote We can check where it will be allocated on the stack by using tools such as Compiler Explorer and search inside the assembly code for expressions such as push, pop, add, sub
rbp
or rsp
.
Doing this we can see that gcc will allocate VLA on the stack.
This is a problem however as the stacksize is limit in size.
The current (soft) limit can be checked in linux
by running i.e.:
ulimit -a
and usually corresponds to 8192kB.
Thus if a user would request an array of doubles (8Bs) with n>8192kB/8B
we will get a segmentation fault.
On the other hand if we would know the maximum size of the array beforehand
it would not even make sense to use VLA in the first place.
We could simply allocate:
double arr[maxsize];
Notes
-
std::vector
on the other hand uses dynamic memory. - gcc supports VLA and thus shows no warnings unless you compile using the
-Wpedantic
flag, which shows warnings of the ISO standard. See also Stackoverflow - It doesn't matter if your compiler also accepts python, the only thing that matters is whether it's C++ or not.
Then you're guaranteed that all compilers will accept it.