5

I have recently migrated to a new laptop - HP dv6119tx (Intel Core i5, 4 GB RAM). It has Windows 7 Home Premium 64 bit installed.

I am trying to create an array of type int of length 10^6 in C++ (Dev C++), which I used to create comfortably on my last laptop (32 bit Windows 7 Ultimate/Ubuntu Linux, 2GB RAM) and every other environment I have programmed on (It should take around 3.5 MB of RAM). But with the current setup, I am getting a "Segmentation Fault" error in Debug Mode.

Screenshot when I am trying to create an array of length 10^5

Screenshot when I am trying to create an array of length 10^6

SCREENSHOTS (EDIT) :
The first screenshot shows 10^5 working on the current setup and 10^6 not. I do not have a screenshot for 10^6 working on my last machine but I have used it many times.

EDIT:
The program would work just fine if I declared the array as global instead or created it dynamically on the heap as

int* a = new int[MAX];  

But what I fail to understand is that when the local array is taking a meager 3.5 MB of memory on the stack (and was working fine on a 2 GB machine), why should this issue surface with a 4GB machine? Is this a user stack space issue? Can it be increased manually?

EDIT 2:
I am particularly asking this question because I have submitted numerous solutions on SPOJ with 10^6 sized arrays created on the stack. With my current setup, I feel crippled not being able to do that. I prefer stack over heap whenever possible because it has no memory leak issues; and local variables over global variables because they are neat and do not mess up the namespace.

Vikesh
  • 2,018
  • 6
  • 23
  • 33
  • The first example is only 10^5. Not sure why you claim 10^6 used to work, since it isn't 10^6. – Raymond Chen Sep 24 '11 at 19:44
  • 2
    This is a great place for this question. – nmichaels Sep 24 '11 at 19:45
  • 1
    @RaymondChen: count again, there are six zeros. – Ernest Friedman-Hill Sep 24 '11 at 19:45
  • 1
    You can increase the stack size but don't. You just tie up a bunch of memory for no good reason. Don't abuse the stack. Put large objects on the heap. – David Heffernan Sep 24 '11 at 19:46
  • 1
    @Raymond You can delete a comment for good. Hover the cursor over the very right hand end of the comment (after the time) and you can see a little cross appear. – David Heffernan Sep 24 '11 at 19:47
  • stack overflow on stackoverflow – BlackJack Sep 24 '11 at 19:48
  • Thanks David. The array size is 10^6. It should take only 3.5 MB of memory on stack. Is that too much, considering my machine is a 4 GB powerhouse? – Vikesh Sep 24 '11 at 19:49
  • As I've already said, Windows gives you only one megabyte of stack per thread by default. – Ernest Friedman-Hill Sep 24 '11 at 19:50
  • 1
    The amount of stack space is set at link time, IIRC -- at which point the compiler and linker and such don't know or care which machine your code will run on, or how much memory it has. Unless you tell the linker and/or compiler to set a bigger stack, you'll get whatever the default is. – cHao Sep 24 '11 at 19:52
  • @RaymondChen - I just edited to mention info of Screenshots. Sorry for the confusion. – Vikesh Sep 24 '11 at 19:54
  • Stack variables do leak, because stack does not decommit. Putting 3MB of data on stack causes the stack to expand, and even after your function returns, the stack does not shrink. – Raymond Chen Sep 24 '11 at 22:25

3 Answers3

9

A four megabyte stack is pretty big. The default size on Windows is 1MB. You need to use the /STACK option to the linker to ask for a larger size.

Ernest Friedman-Hill
  • 80,601
  • 10
  • 150
  • 186
  • 2
    The stack is limited in size by design. You can increase the stack size, but for such large objects it's probably better to find a different way to allocate them. – Keith Thompson Sep 24 '11 at 19:47
  • True, in general. I'm using a hands-off library in one of my projects right now, though, that needs a 2MB stack to initialize properly, hence my mindset is that *sometimes* this is necessary. – Ernest Friedman-Hill Sep 24 '11 at 19:49
8

Arrays created like that are stored on the stack. However, the stack has very limited size, therefore you are hitting a stackoverflow and a crash.

The way to do it is to allocate it on the heap:

int *a = (int*)malloc(MAX * sizeof(int));

//  Do what you need to do.

//  Free it when you're done using "a".
free(a);
Mysticial
  • 464,885
  • 45
  • 335
  • 332
  • Thanks, I just edited the question to include this viewpoint. Can you suggest now? – Vikesh Sep 24 '11 at 19:44
  • Yes, the user stack space is (by default) very small. When you declare a local array `int a[MAX]`, it is placed on the stack. So a large array can overrun the stack. – Mysticial Sep 24 '11 at 19:47
  • Just a note: VLAs are a C99 Feature. Also these code lines may end up writing in memory they should not, and even try to free something that never really existed in case malloc fails. add an if(a){ ... }. The cast is not needed in case it is C. –  Sep 24 '11 at 19:53
  • 1
    @Muggen: Agreed, though it's not a VLA since `MAX` is a constant. Also the question is tagged both C and C++, so I gave a solution that would work in both. – Mysticial Sep 24 '11 at 19:56
  • @Mysticial, oops correct about the macro. I understand the problem about both tags. –  Sep 24 '11 at 19:59
  • Thanks @Mysticial. I am aware that this is a stack overflow issue and also that it can be fixed by migrating to heap (global/dynamic). I wanted to know why exactly 3.5 MB of memory is causing an overflow while the RAM is 4 GB. As you and Ernest mentioned, this could be because the default user stack on Windows is very limited. – Vikesh Sep 24 '11 at 20:01
  • @Vikesh: It's not just Windows, it's most OS's in general. You can increase the stack size, but doing so is not meant to be a replacement for the heap. (In other words, don't try to increase the stack size to > 1GB so that you can create an array that's 1GB large.) – Mysticial Sep 24 '11 at 20:05
  • @Mysticial - Thanks a lot. I take a note :) – Vikesh Sep 24 '11 at 20:07
2

Instead of malloc'ating memory you can specify your buffer as static. E.g.:

static int a[MAX];

Advantage of this approach is that you need not to track your memory allocation.

trashkalmar
  • 883
  • 5
  • 11