0

I have a simple initialization-population routine in C, that works fine in Linux. However when I try to run it in Code::Blocks, it produces a segmentation fault.

The code is below:

#include <stdio.h>
#include <stdlib.h>

double **rho, **ux, **uy;
double** allocate_double_array(int nx, int ny)
{
   int i;
   double** array=(double**) malloc( (nx * sizeof(double*)) + (nx*ny * sizeof(double**)) );

   if (array==NULL) printf("Memory allocation failed!\n");

   for(i=0; i<nx; ++i)
   {
       array[i] = (double*)(array + nx) + i * ny;
   }
   return array;
}

int main()
{
    int nx = 100;
    int ny = 100;
    int x,y;

    rho   = allocate_double_array(nx,ny);
    ux    = allocate_double_array(nx,ny);
    uy    = allocate_double_array(nx,ny);

    printf("Memory allocated_alter\n");
    for (x=0; x<nx; x++)
    {
        for (y=0; y<ny; y++)
        {
            rho[x][y] = 1.0;
            ux[x][y] = 2.0;
            uy[x][y] = 3.0;
        }
    }
    printf("Initialization Complete\n");
    return 0;
}

Any idea where I am going wrong?

Mike Kinghan
  • 55,740
  • 12
  • 153
  • 182
  • Any idea where it's going wrong? – meaning-matters Jan 08 '18 at 10:46
  • 1
    [Please see this discussion on why not to cast the return value of malloc() and family in C..](https://stackoverflow.com/q/605845/2173917) – Sourav Ghosh Jan 08 '18 at 10:46
  • 1
    https://ericlippert.com/2014/03/05/how-to-debug-small-programs/ and https://stackoverflow.com/questions/2069367/how-to-debug-using-gdb might be helpful read. – Yunnosch Jan 08 '18 at 10:48
  • Why this cast: `... = (double*)(array + nx) + i * ny;`? Any other reason but to silence the compiler warning you , that there is something going on? – alk Jan 08 '18 at 11:04
  • Thank you all for the comments. I am by no means an accomplished programmer, thus the style/efficiency errors. Do you think any of the suggestions might be the reason for the SIGSEGV? Especially given that it runs fine in a different OS. – Peter Hristov Jan 08 '18 at 11:27
  • The size of the malloc'ed memory is calculated incorrectly: `+ (nx*ny * sizeof(double**))` should be `+ (nx*ny * sizeof(double))` – Gerhardh Jan 08 '18 at 11:33
  • Similar problem when you initialize the pointers: `array[i] = (double*)(array + nx) + i * ny;` The `+ i * ny` part increases the address by multiples of `double*` instead of `double` – Gerhardh Jan 08 '18 at 11:35
  • @Gerhardh This also helped! Thank you! Can I then turn the discussion a bit and ask, why was it working correctly in Linux? – Peter Hristov Jan 08 '18 at 11:35
  • 1
    In the end I assume that it depends on the size of `double` and `double**`. This could be different on both machines – Gerhardh Jan 08 '18 at 11:36

1 Answers1

1

In the double allocation function.

Why are you using the malloc function like this?

Try

double** array=(double**) malloc( (nx * sizeof(double*));

and then in the loop

array[i]=(double*)malloc( (ny * sizeof(double));

nabil.douss
  • 634
  • 4
  • 10
  • This resolved the issue! Could you please explain why this is? – Peter Hristov Jan 08 '18 at 11:32
  • double** is a pointer to an array of pointers to an array of type double. You only have to allocate nx * sizeof(double*) because `array` points to an array of type double* of size nx. Then for every element of `array` you have to allocate ny*sizeof(double) because every element is a pointer to an array of type double of size ny. – nabil.douss Jan 08 '18 at 11:43