2

I'm running some code which may be pointing out I don't understand the difference between the heap and stack that well. Below I have some example code, where I either declare an array on the stack or the heap of 1234567 elements. Both work.

int main(int argc, char** argv){

  int N = 1234567;

  int A[N];

  //int* A = new int[N];

}

But if we take N to be 12345678, I get a seg fault with int A[N], whereas the heap declaration still works fine. (I'm using g++ O3 -std=c++0x if that matters). What madness is this? Does the stack have a (rather small) array size limit?

trincot
  • 317,000
  • 35
  • 244
  • 286
andyInCambridge
  • 1,215
  • 2
  • 13
  • 27
  • 2
    The stack is working memory for supporting function call execution. It is relatively small because it is expexted that it will use only a few bytes for most calls. You can expand it by changing your compilation settings. – Miltos Kokkonidis Nov 29 '12 at 23:31

2 Answers2

6

This is because the stack is of a much smaller size than the heap. The heap can occupy all memory available to the program. By default VC++ compiles the stack with a size of 1 MB. The stack offers better performance but is for smaller quantities of data. In general it is not used for large data structures. This is why functions accepting lists/arrays/dictionaries/ect in c++ generally take a pointer or reference to that structure. Parameters passed by value are copied onto the stack and passing such structures would frequently cause programs to crash.

In your example you're using N int's, an int is 4 bytes. That makes the size of A[N] ~4.7 MB, much larger than the size of your stack.

evanmcdonnal
  • 46,131
  • 16
  • 104
  • 115
  • The stack does *not* offer performance that is any better or worse than the heap's performance. Stack and heap are on the same memory chips! It is the heap memory allocation functions (mailloc and co) that are more complex and slower than the ridiculously simple and fast way stack storage is allocated :-) – Miltos Kokkonidis Nov 30 '12 at 02:13
  • @MiltiadisKokkonidis That makes no sense. If allocation on the stack is more performant then the stack is more performant. – evanmcdonnal Nov 30 '12 at 03:32
  • It makes perfect sense. Do you think accessing four bytes of memory is faster if you call them stack memory than if you call them heap memory? No. :-) Also it is possible to allocate a chunk of 20 MB of heap memory and store its location in a pointer called fastMem and instead of having p = malloc(n); do p = fastMem; fastMem += p; This would make allocation on the heap quite similar to allocation in the stack and with equally blazing fast performance. – Miltos Kokkonidis Nov 30 '12 at 03:40
2

The heap grows dynamically with allocation through malloc and co. The stack grows with each function call made in the course of running a program. The return address, arguments, local variables are usually stored in the stack (except that in certain processor architectures a handful of these are stored in registers instead). It is also possible (but not common) to allocate stack space dynamically.

The heap and the stack compete for the use of the same memory. You can think on one growing left to right and the other growing right to left. There is a possibility that, if left unchecked, they may collide. The stack is typically restrained from growing beyond a certain bound. This is relatively small because it is expected that it will use only a few bytes for most calls and only a few stack levels will be used. The limit is small but sufficient for most tasks. You can expand this limit by changing your build settings (not for Linux ELF binaries though) or by calling setrlimit. The OS may also impose a limit which you can change. There may be soft and hard limits (http://www.nics.tennessee.edu/node/327).

Going into greater detail about the limits falls outside the scope of the question. The bottomline is that the stack is limited and it is quite small because it competes with the heap for actual memory and for typical applications it need not be bigger.

http://en.wikipedia.org/wiki/Call_stack

Miltos Kokkonidis
  • 3,888
  • 20
  • 14
  • 1
    It's not only for function calls. – Luchian Grigore Nov 29 '12 at 23:32
  • Please explain -- it is too late at night for my brain to work :-) – Miltos Kokkonidis Nov 29 '12 at 23:36
  • @MiltiadisKokkonidis: It's also for automatic variables – Mooing Duck Nov 30 '12 at 00:20
  • The local variables are part of supporting the function calls in the sense that you cannot call a function unless you allocate space for them and you only allocate memory for a function's local variables for an invocation of the function. In fact parameters and local variables are treated in the exact same way as far as memory allocation goes; the only difference is that the caller initialises the arguments and the function's code is responsible for initialising the local variables it wishes to :-) – Miltos Kokkonidis Nov 30 '12 at 00:28