5

In my C program, when I try to assign this array value:

double sample[200000][2];

I get a segmentation fault error. But when I use:

double sample[20000][2]

it works!! Is there a limit to these index values?

Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
james
  • 221
  • 5
  • 16

2 Answers2

9

It looks like you tried to reserve space for 200,000 x 2 = 400,000 double values, and each double is 8 bytes, so you tried to reserve around 3.2 Megabytes.

Even though your machine likely has a couple Gigs of memory, stack space is limited per-process and per-thread and may well be limited to 1 or 2 megabytes. So you cannot allocate 3 megs, and you crash.

To fix this, you want to change to dynamic memory, using malloc.
That will let you allocate from heap-space which is much more plentiful than stack-space.

To use malloc:

double (*sample) [200000];
s = malloc(sizeof(*sample) * 2); 
sample[0][0] = 0.0;
sample[1][199999] = 9.9;
Zan Lynx
  • 53,022
  • 10
  • 79
  • 131
abelenky
  • 63,815
  • 23
  • 109
  • 159
  • @ZanLynx: You are partially right, I forgot a level of indirection (`*`). Fixed now. – abelenky Nov 04 '13 at 23:04
  • I have to agree with @ZanLynx I don't see how your allocation code works. – Shafik Yaghmour Nov 04 '13 at 23:17
  • I edited your code example with one that I tried out. – Zan Lynx Nov 04 '13 at 23:21
  • @ZanLynx that is still wrong, so the `200000` *double* * will be in automatic storage and the much smaller second dimension will be dynamic which is definitely not the original intention. – Shafik Yaghmour Nov 05 '13 at 22:48
  • @ShafikYaghmour: Automatic storage? No. In the code above `sample` is a pointer to an array of 200,000 doubles. The `malloc(sizeof(*sample)*2)` requests dynamic allocation of two of those arrays for 400,000 doubles total. – Zan Lynx Nov 05 '13 at 23:06
6

You are likely overflowing your stack, since that is a automatic variable in most modern implementation they will allocated on the stack which has limited size.

For example the stack size in visual studio defaults to 1MB but is modifiable. There is a more complete list of typical stack sizes here:

SunOS/Solaris   8172K bytes
Linux           8172K bytes
Windows         1024K bytes
cygwin          2048K bytes

An alternative to allocating on the stack if you have a large amount of data is to use dynamic allocation via malloc. The C FAQ has a good reference on How can I dynamically allocate a multidimensional array?, modifying their two-dimensional example for double:

#include <stdlib.h>

double **array1 = malloc(nrows * sizeof(double *));
for(i = 0; i < nrows; i++)
   array1[i] = malloc(ncolumns * sizeof(double));
Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
  • 1
    Just some more stack comments: Some systems have "unlimited" stack size, as it grows on demand. But when threading is added stacks suddenly have fixed size because each stack needs a unique location and will quickly run into neighboring memory allocations. – Zan Lynx Nov 04 '13 at 22:49
  • how can i modify the stack size ? i using gcc compiler here. – james Nov 04 '13 at 22:51
  • @james what operating system? – Shafik Yaghmour Nov 04 '13 at 22:52
  • Linux stack information: http://stackoverflow.com/questions/2656722/is-there-a-limit-of-stack-size-of-a-process-in-linux – Zan Lynx Nov 04 '13 at 22:52
  • @ZanLynx : do you perhaps happen to know what the standard says about the maximum array size? I guess it's implementation-defined, but I'm curious. – Daniel Kamil Kozar Nov 04 '13 at 22:53
  • @James: *"How can I modify the stack size?"* is the wrong question. The proper question is *"How can I avoid allocating on the stack?"* – abelenky Nov 04 '13 at 22:54
  • 1
    @DanielKamilKozar: I do not think the standard defines a minimum size. One a 16-bit computer, you'd be limited to 64KB objects for example. And yet, that used to be a common C programming environment. – Zan Lynx Nov 04 '13 at 22:55
  • @DanielKamilKozar the standard does not talk about the stack it just talks about automatic storage duration. – Shafik Yaghmour Nov 04 '13 at 22:57