views:

868

answers:

9

The following code is generating a stack overflow error for me

int main(int argc, char* argv[])
{
    int sieve[2000000];
    return 0;
}

How do I get around this? I am using Turbo C++ but would like to keep my code in C

EDIT:

Thanks for the advice. The code above was only for example, I actually declare the array in a function and not in sub main. Also, I needed the array to be initialized to zeros, so when I googled malloc, I discovered that calloc was perfect for my purposes.

Malloc/calloc also has the advantage over allocating on the stack of allowing me to declare the size using a variable.

+1  A: 

There should be an option someplace to set the stack size.

Hemal Pandya
A: 

Could you try to rewrite the logic to avoid having to reserve a large space upfront and that too on the stack. Attacking these 2 things (upfront allocation, stack allocation) should give you a workaround.

Mohit Chakraborty
+2  A: 
int main(void)
{
    int *sieve = xmalloc(2000000 * sizeof(int));
    /* do stuff */
    free(sieve);
    return 0;
}
J.F. Sebastian
+14  A: 

Your array is way too big to fit into the stack, consider using the heap:

int *sieve = (int *)malloc(sizeof(int)*2000000);

If you really want to change the stack size, take a look at this document.

arul
As this is C, you need not (and in fact, should not) cast the return value of malloc.
aib
Why wouldn't you cast the result of malloc? Wouldn't you have to cast it from void* in order to do much of anything with it?
yodaj007
+1  A: 

You would be better off allocating it on the heap, not the stack. something like

int main(int argc, char* argv[])
{
    int * sieve;
    sieve = malloc(20000);
    return 0;
}
Cogsy
you forgot to free(sieve)
Nathan Fellman
+1  A: 

That's about 7MB of stack space. In visual studio you would use /STACK:###,### to reflect the size you want. If you truely want a huge stack (could be a good reason, using LISP or something :), even the heap is limited to small'sh allocations before forcing you to use VirtualAlloc), you may also want to set your PE to build with /LARGEADDRESSAAWARE (Visual Studio's linker again), but this configure's your PE header to allow your compiled binary to address the full 4GB of 32'bit address space (if running in a WOW64). If building truely massive binaries, you would also typically need to configure /bigobj as an additional linker paramerter.

And if you still need more space, you can radically violate convention by using something simular to (again MSVC's link) /merge:, which will allow you to pack one section into another, so you can use every single byte for a single shared code/data section. Naturally you would also need to configure the SECTIONS permissions in a def file or with #pgrama.

RandomNickName42
Am just re-reading the answers to this question, have to give +1 for the in-depth answer here
Patrick McDonald
+7  A: 

There are 3 ways:

  1. Allocate array on heap - use malloc(), as other posters suggested. Do not forget to free() it (although for main() it is not that important - OS will clean up memory for you on program termination).
  2. Declare the array on unit level - it will be allocated in data segment and visible for everybody (adding static to declaration will limit the visibility to unit).
  3. Declare your array as static - in this case it will be allocated in data segment, but visible only in main().
qrdl
I'd just make it static: `main()` should only be called once, so there are no pitfalls; no need for `malloc()` here...
Christoph
A: 

Is there some reason why you can't use alloca() to allocate the space you need on the stack frame based on how big the object really needs to be?

If you do that, and still bust the stack, put it in allocated heap. I highly recommend NOT declaring it as static in main() and putting it in the data segment.

If it really has to be that big and your program can't allocate it on the heap, your program really has no business running on that type of machine to begin with.

What (exactly) are you trying to accomplish?

Tim Post
I am using problems from ProjectEuler.net to learn C, and am implementing the Sieve of Eratosthenes algorithm, so it does have to be that big. malloc works fine for my purposes though
Patrick McDonald
+1  A: 

Use malloc. All check the return type is not null, if it is null then your system simply doesn't have enought memory to fit that many values.