2

OpenMP で動的メモリ割り当てを使用して行列乗算を実装しようとしています。プログラムを正常にコンパイルすることができましたが、実行しようとすると、 ./ 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);

二重ポインターで malloc を使用する方法がバグの原因であると思います。

また、このプログラムには、2 つの行列を生成し、乗算を順次 1 回、openMP で 1 回実行する次の関数が含まれています。

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];
      }
    }
4

1 に答える 1

0
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;
}

"for" ステートメントがループ内で実行された後の次のステートメントのみ中括弧を外すと、ループの終了後に "matrix2" 行が実行され、その時点で i と j は範囲外になるため、(double*) matrix2[i] はごみです。matrix2[i] にアクセスすると、ヒープ レイアウトに応じてセグメンテーション違反が発生する場合と発生しない場合があります。

それだけの問題ではありません: ループ内で matrix[i][size*size - 1] にアクセスしているときに、matrix[i] が sizeof(double) * size の配列へのポインターとして割り当てられます。

C 派生言語では、通常、"if"、"do"、"for"、"case"、および "while" ステートメントの括弧を省略することは悪い考えです。さらに行を追加する必要があると想像すると、面倒になる可能性があります。コードがより複雑になると、読みにくく、推論するのも難しくなります。

于 2015-05-02T16:56:42.827 に答える