Why can't I just use a variable called from the stack, as opposed to a variable called from the heap?
Heap allocation give you more control over memory.
Also, there are limitations, when it comes to stack variables.
//warning : applies only to PCs, may not be true for other architecthures I'm not familiar with. (mips, motorola 68000, etc. Anything that is not x86-related, bascially).
Variables created in the stack can change during runtime right?
Their SIZE can't change.
Stack has limited size. Size is decided by operating system AND compiler. If stack becomes too big, program dies because of stack overflow. Classic example:
int main(int argc, char** argv){
char buffer[1024*1024*64];
buffer[0] = 0;
return 0;
}
This program will crash if compiled with default settings on windows and it should crash on linux as well. That's because default stack size is 1 MB on 32bit windows and 8 MB on 32 bit linux (system may change this, though, using ulimit
), and 64-megabyte array won't fit on stack.
If your varaible is located between two other variables on stack, you can't change its size, no matter what. At least on x86/64 cpus.
- You can, in theory, increase size of stack array if it is the last thing on stack. (if I remember correctly, there was possibly non-standard C function called alloca that could allocate arrays on stack). However, you'll still hit stack size limit.
To understand WHY there are such limits, you need to step back from C++, and learn a bit of assembly. Try to find a book that covers segments (data/code/stack), explains where function return addresses are stored, and, preferably, tells you about protected mode. That should help.
Of course, there is a bit of a problem. Assembly knowledge will help only for particular family of CPUs. Different CPU with C++ compiler may use different rules.
--update--
Why does dynamic memory allow the size of arrays to be allocated during runtime?
Depending on arch, stack size might be more or less fixed. You have some memory area reserved for stack, say at addresses 0x00100000..0x00200000 and all variables locaated on stack will be somewhere in this area. Location of new variables is determined by (if I remember correctly) "stack pointer", which moves in direction determined by CPU. Whenyou add new variable on stack, stack pointer moves (direction of movement determined by CPU) by size variable, and variable will be located in addresses between old and new memory position. Because stack space can be limited, and because variables are adjacent (plus function return addresses are also stored on stack) you can't suddenly jam 2GB array in the middle of it. The main problem is not actually limited size, but variables being adjacent to each other.
Now, HEAP is different. Heap allocation, in theory, can return you any address from within entire address space, but in practice some addresses will be reserved (on 32bit windows you have only 2..3GB available out of entire 4GB space, for example). Because you have MUCH more space available, and because allocated blocks don't have to be adjacent, you can freely allocate big array and (in theory) even resize them (in practice functions like realloc probably just make new array, copy old contents into new array, then kill old array).
Please note that there are additional hidden details. For example, addresses returned to you by heap allocation functions are not physical addresses, but virtual addresses, and in reality OS can move your program in physical memory around, while (virtual) addresses used within program will remain unchanged.
That's why I suggest to read assembly book. you don't have to learn assembly in depth, but having some general idea of what happens behind the scenes, will certainly help.