What happens when you ask for more space in the stack than is available?

advertisements

This question is based on C / C++ memory allocation.

I read up on the differences between the stack and heap and one things confuses me. One should allocate memory in the heap for large objects, but one can also do so in the stack as a local variable.

From this thread (C/C++ maximum stack size of program) I understood that the stack is limited and the limits are relatively low (7.4MB maximum).

I tested this limit with the following program:

#include <vector>
int main() {
std::vector<double> test;

for (int i = 0; i < 5000000; i++){
    test.push_back(i);
}

return 0;
}

The total allocated memory is 8 Byte * (5.000.000) = 40MByte. This does not seem to provoke any kind of error. I read on this resource (https://software.intel.com/en-us/articles/determining-root-cause-of-sigsegv-or-sigbus-errors), that a stack overflow might provoke a segmentation fault or bus error.

So I guess, the question is: What happens when you "allocate" more memory in the stack than you can?


std::vector allocates memory on the heap, not the stack. If you want to test tack allocation, the simplest way is with a program like:

#include <cstdio>
int main(void) {
    char temp[1024*1024*40] = {};
    printf("%s\n",temp);
    return 0;
}

(N.B. the printing is necessary to prevent the buffer being optimized away.)
This allocates 40 MiB on the stack, and produces a stack overflow (see live).

Another method is to call a function recursively. For example:

unsigned factorial_times_2(unsigned n) {
    unsigned result;

    if (n<2u) result=1u;
    result = n * (factorial_times_2(n-1u)/2u);

    return result * 2u;
}
int main(void) {
    return factorial_times_2(~0u)/2u;
}

This is a simple modification of the classic recursive factorial function (modified, because modern compilers will make the simple factorial tail-recursive). At runtime, it will try to make on the order of 4 billion stack frames. A stack overflow is produced (see live).


A stack overflow means, as you might expect, that you exceeded the memory given to the stack. Since the stack is typically allocated its own pages, going outside the stack walks outside a valid mapped memory address.

Therefore, the stack overflow usually results in a segmentation fault (as happens in the examples above). On Windows, it is called an access violation. If you're less lucky, it will corrupt your program's data, and you won't find out until later.