2

In my C code I am allocating memory for 2d array double E[2000][2000]; but when I run it gets a runtime error Segmentation fault(core dumped) and when I reduce the array size to somewhere around 900 then the code runs fine.

Why it is showing runtime error since double take 64 bits memory (IEEE standard) so the code should take approximately 32MB which is not much compared to the ram size.And if it is not supported in C then how should I proceed if my maximum number of data that I have to store is 4000000 each are floating point numbers.

Saurabh
  • 156
  • 6

3 Answers3

6

Are you declaring E as a local variable ? If so, you're running out of stack memory.

void func()
{
    double E[2000][2000]; /// definitely an overflow
}

Use dynamic allocation:

double* E = malloc(2000 * 2000 * sizeof(double));
/// don't forget to "free(E);"  later

Or if you need the 2D array, use a zig-zag:

double** E = malloc(2000 * sizeof(double*));

/* check that the memory is allocated */
if(!E)
{
    /* do something like exit(some_error_code);  to terminate your program*/
}

for(i = 0 ; i < 2000 ; i)
{
      E[i] = malloc(2000 * sizeof(double));

     /* check that the memory for this row is allocated */
     if(!E[i])
     {
        /* do something like exit(some_error_code);  to terminate your program*/
     }
}

Then the deallocation is a little more complicated:

for(i = 0 ; i < 2000 ; i)
{
      free(E[i]);
}

free(E);

P.S. If you want to keep all of you data in a continuous way, there's a trick (code from Takuya Ooura's FFT Package)

double **alloc_2d(int n1, int n2)
{
    double **ii, *i;
    int j;

    /* pointers to rows */
    ii = (double **) malloc(sizeof(double *) * n1);

    /* some error checking */
    alloc_error_check(ii);

    /* one big memory block */
    i = (double *) malloc(sizeof(double) * n1 * n2);

    /* some error checking */
    alloc_error_check(i);

    ii[0] = i;
    for (j = 1; j < n1; j++) {
        ii[j] = ii[j - 1] + n2;
    }
    return ii;
}

void free_2d(double **ii)
{
    free(ii[0]);
    free(ii);
}

The you just call

double** E = alloc2d(2000, 2000);

and

free_2d(E);
Viktor Latypov
  • 14,289
  • 3
  • 40
  • 55
  • 3
    `malloc/free` instead of `new/delete` for `C`? – Shawn Chin Oct 02 '12 at 10:04
  • Also, since dynamic allocations can fail, check `malloc()`'s return value for `NULL` before using it. – unwind Oct 02 '12 at 10:09
  • @SteveJessop appreciate your fair play and avoiding redundancy – fkl Oct 02 '12 at 10:17
  • @unwind: Checking `malloc()` for `NULL` makes sense if you can handle (and/or recover) from the problem. Chances are that just terminating the process in case no further memory can be allocated is among your best options. – Frerich Raabe Oct 02 '12 at 10:22
  • @FrerichRaabe: my internet connection dropped for a few moments, I've submitted a non-NULL check. I think there's not much to say here. At least before the OP adds some clarification for his question. – Viktor Latypov Oct 02 '12 at 10:40
  • @Frerich: checking makes sense even if you can't really handle/recover from the problem. Even the worst-case option of calling `abort` or `exit` (which Viktor has used here because he has no idea of the structure of the questioner's program, and so cannot design anything else) is better than provoking UB when you try to use the null pointer. – Steve Jessop Oct 02 '12 at 10:48
  • @SteveJessop: I concur (I got so used to `xmalloc` that I forgot this doesn't happen implicitely...). In fact, I guess it also helps to satisfy lint-style tools which check for this. – Frerich Raabe Oct 02 '12 at 10:54
5

I assume you are allocating it on the stack by simply

double E[2000][2000];

which will probably be more than stack size allocated to your program.

Try using malloc (or new in c++) or increase the default stack size of your program using options. gcc can be configured using setrlimit() for this purpose.

setting stack size in gcc

Keep in mind that even if stack size is increased, an array of this size should be global

You can also use a single statement to allocate a 2D array on heap if one dimension is fixed in size

double (* E)[COLUMN_SIZE];
int rows = 20; // this is dynamic and can be input from user at run time
E = malloc(rows * sizeof(*E)); // this needs to be freed latter

A more detailed similar example allocating 2d array without loops

Community
  • 1
  • 1
fkl
  • 5,412
  • 4
  • 28
  • 68
0

It depends on where you allocate the array. Using stack space will probably cause an overflow (unless you get the linker to allocate an extra large stack).

For example, this might not work

int main()
{
    double E[2000][2000];   // Likely an overflow
}

However, moving the array to the static memory area

double E[2000][2000];

int main()
{
   // use E here
}

will probably avoid the problem.

Bo Persson
  • 90,663
  • 31
  • 146
  • 203