The stack has a limited size. On some windows systems it's 1 MB. You can programatically change the stack size, but more often than not that's a bad idea.
You have a different stack on each thread. Stack variables are always freed at the end of a scope. E.g.
void MyFunction
{ // begin of scope 1
std::string mouse("feep");
for (int i = 0; i < 10000000; i++)
{ // begin of scope 2
int x = 1; // x is on the stack
std::string cow("moo"); // cow is on stack
// end of scope 2, cow is destroyed then the stack is freed for cow and x before the next iteration of the loop begins
}
return; // end of scope 1, mouse is destroyed ant the stack is freed for mouse
}
At any one time the above code will at most have mouse, i, x, and cow on the stack. If you use recursion you can can end up with a very deep stack, which overflows. E.g.
void StackOverflowIncoming()
{ // begin of scope
int aVariableOnTheStack = 0;
StackOverflowIncoming();
// end of scope
}
The above function opens new scopes forever and never leaves a scope, so at some point it will overflow.
Another way to overflow the stack is alloca, which directly allocates the stack (which is then freed as soon as the scope in which it was allocated closes. Simply use alloca to allocate 10 MB on the stack if the maximum stack size is 1 MB. That can also be achieved by allocating a huge structure on the stack.
void InstantStackOverflow()
{
char buffer[1<<24];
}
For a more detailed example of allocation just too much on the stack see this question.
The final and most creative way to overflow the stack is to corrupt the program state so the program gets horribly confused and fails to clean up the stack. Usually you do this by using language features that result in undefined behaviour, like this:
void TryToCorruptTheStack()
{ // begin of scope
char buffer[1];
for (int i = -20; i < 20; i++)
buffer[i] = 5;
// end of scope
}
For a more detailed example of stack corruption see this question.