-1

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?

trincot
  • 317,000
  • 35
  • 244
  • 286
Slyforce
  • 5
  • 4

2 Answers2

0

The behavior of overflowing the stack is platform dependent. The official term may be "undefined behavior", meaning anything could happen.

Platforms do not need to implement a stack, although it is a common technique.

Some platforms have memory set aside for both stack and heap, and have them "grow" towards each other (draw a picture). So if the stack overflows, it starts writing over the heap and vice-versa.

Some platforms may have hardware fences set up and when the processor accesses memory out of range, a hardware exception is generated. The OS would process that exception.

Another example is that your program starts writing to some kind of hardware device, such as a USB controller or disk drive controller.

In summary, the behavior of a Stack Overflow is platform dependent, including the recovery if any.

Thomas Matthews
  • 56,849
  • 17
  • 98
  • 154
0

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.

geometrian
  • 14,775
  • 10
  • 56
  • 132