Search code examples
pointersmallocopenmpdouble-pointer

Segmentation fault (core dumped) OpenMP


I am trying implement a matrix multiplication with dynamic memory allocation with OpenMP. I manage to get my program to compile fine but when i am trying to execute it i am getting ./ line 14: 17653 Segmentation fault (core dumped) ./matrix.exe $matrix_size

    int main(int argc, char *argv[]){
  if(argc < 2){
    printf("Usage: %s matrix/vector_size\n", argv[0]);
    return 0;
  }

  int size = atoi(argv[1]);
  double **matrix2 = (double **)malloc(sizeof(double*)*size);
  double **matrix = (double **)malloc(sizeof(double*)*size);
  double **result_sq = (double **)malloc(sizeof(double*)*size);
  double **result_pl = (double **)malloc(sizeof(double*)*size);
  int t;
  for (t =0; t<size; t++) {
      matrix[t]= (double *)malloc(sizeof(double)*size);
      matrix2[t]= (double *)malloc(sizeof(double)*size);
      result_pl[t]= (double *)malloc(sizeof(double)*size);
      result_sq[t]=(double *)malloc(sizeof(double)*size);
  }
  matrix_vector_gen(size, matrix, matrix2);

I believe that the way that I using the malloc with the double pointer caused the bug.

Also, the program contains the following function for generating the two matrices and performing a the multiplication once sequentially and once with openMP.

void matrix_vector_gen(int size, double **matrix, double **matrix2){
  int i,j;
  for(i=0; i<size; i++)
        for(j=0; j<size*size; j++)
            matrix[i][j] = ((double)rand())/5307.0;
            matrix2[i][j] = ((double)rand())/65535.0;
}
void matrix_mult_sq(int size, double **matrix2,
               double **matrix_in, double **matrix_out){
  int i, j, k;

  for(i=0; i<size; i++){

    for(j=0; j<size; j++)
        matrix_out[i][j] = 0.0;
        for(k=0; k<size; k++)
            matrix_out[i][j] += matrix_in[i][k] * matrix2[k][j];
  }
}

void matrix_mult_pl(int size, double **matrix2,
               double **matrix_in, double **matrix_out){
  int i, j, k;


    # pragma omp parallel               \
      shared(size, matrix2, matrix_in, matrix_out)  \
      private(i,j,k)
    # pragma omp for
      for(i=0; i<size; i++){

        for(j=0; j<size; j++)
            matrix_out[i][j] = 0.0;
            for(k=0; k<size; k++)
                matrix_out[i][j] += matrix_in[i][k] * matrix2[k][j];
      }
    }

Solution

  • void matrix_vector_gen(int size, double **matrix, double **matrix2){
      int i,j;
      for(i=0; i<size; i++)
            for(j=0; j<size*size; j++)
                matrix[i][j] = ((double)rand())/5307.0;
                matrix2[i][j] = ((double)rand())/65535.0;
    }
    

    when you leave braces out only the next statement after the "for" statement is executed in the loop, so the "matrix2" line is executed after the loops end, at which point i and j are out of bound, therefore (double*) matrix2[i] is rubbish; accessing matrix2[i] may or may not cause a segfault depending on the heap layout, but accessing matrix2[i][j] most likely will since there's no telling where it's going.

    That's not the only problem: matrix[i] is allocated as a pointer to an array of sizeof(double) * size, while you're accessing matrix[i][size*size - 1] in the loop.

    In C-derived languages, leaving out the braces for "if", "do", "for", "case" and "while" statements usually is a bad idea; imagine having to add more lines, it can get bothersome. It's hard to read and reason about as well when the code gets more complicated.