Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Could not allocate memory

Tags:

c

memory

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.

like image 433
Saurabh Avatar asked Jul 19 '26 08:07

Saurabh


1 Answers

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);
like image 118
Viktor Latypov Avatar answered Jul 21 '26 23:07

Viktor Latypov



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!