8

for example I can do

int *arr;
arr = (int *)malloc(sizeof(int) * 1048575);

but I cannot do this without the program crashing:

int arr[1048575];

why is this so?

skaffman
  • 398,947
  • 96
  • 818
  • 769
ladookie
  • 1,343
  • 4
  • 21
  • 24

3 Answers3

11

Assuming arr is a local variable, declaring it as an array uses memory from the (relatively limited) stack, while malloc() uses memory from the (comparatively limitless) heap.

Adam Liss
  • 47,594
  • 12
  • 108
  • 150
  • It is not necessary for a pointer to point to memory in the heap, it can point to memory on the stack, or in block storage. – Jay Elston Jun 29 '11 at 03:12
  • 1
    @Jay: That's correct. But, by definition, `malloc()` always allocates memory from the heap. There are other functions (such as `alloca()`) that allocate memory from the stack. Declaration of a local array will always allocate memory from the stack unless it's declared static. Globals are allocated from the heap. – Adam Liss Jun 29 '11 at 03:18
  • I guess my question then is why does the stack have much less space available to it. I though the stack and the heap both had the same amount of room to grow and that they just grew into eachother (the stack down and the heap up.) – ladookie Jun 29 '11 at 03:28
  • 1
    Conceptually (and in simple systems) that's true. But in complex, multi-threading systems, each thread needs its own stack, while heap space can be shared. Some more info here: http://stackoverflow.com/questions/79923/what-and-where-are-the-stack-and-heap – Adam Liss Jun 29 '11 at 03:55
2

If you're allocating these as local variables in functions (which is the only place you could have the pointer declaration immediately followed by a malloc call), then the difference is that malloc will allocate a chunk of memory from the heap and give you its address, while directly doing int arr[1048575]; will attempt to allocate the memory on the stack. The stack has much less space available to it.

The stack is limited in size for two main reasons that I'm aware of:

  1. Traditional imperative programming makes very little use of recursion, so deep recursion (and heavy stack growth) is "probably" a sign of infinite recursion, and hence a bug that's going to kill the process. It's therefore best if it is caught before the process consumes the gigabytes of virtual memory (on a 32 bit architecture) that will cause the process to exhaust its address space (at which point the machine is probably using far more virtual memory than it actually has RAM, and is therefore operating extremely slowly).
  2. Multi-threaded programs need multiple stacks. Therefore, the runtime system needs know that the stack will never grow beyond a certain bound, so it can put another stack after that bound if a new thread is created.
Ben
  • 68,572
  • 20
  • 126
  • 174
  • I guess my question then is why does the stack have much less space available to it. I though the stack and the heap both had the same amount of room to grow and that they just grew into eachother (the stack down and the heap up.) – ladookie Jun 29 '11 at 03:16
  • @ladookie: I've added some information that points to why the stack size is so limited compared to the heap. – Ben Jun 29 '11 at 03:41
1

When you declare an array, you are placing it on the stack.

When you call malloc(), the memory is taken from the heap.

The stack is usually more limited compared to the heap, and is usually transient (but it depends on how often you enter and exit the function that this array is declared in.

For such a large (maybe not by today's standards?) memory, it is good practice to malloc it, assuming you want the array to last around for a bit.

tchen
  • 2,212
  • 1
  • 16
  • 18