0

このコードを実行するとセグメント化エラーが発生します。誰でも知っている理由は?ありがとう。C - 行列乗算セグメンテーションフォールト

#include <stdio.h> 

int main() 
{ 
    double **m1, **m2, **mr; 
    int m1_rows, m1_cols, m2_rows, m2_cols, mr_rows, mr_cols; 
    int i, j, k; 

    printf("Enter number of rows for matrix 1: "); 
    scanf("%d", &m1_rows); 

    printf("Enter number of columns for matrix 1: "); 
    scanf("%d", &m1_cols); 

    printf("Enter number of rows for matrix 2: "); 
    scanf("%d", &m2_rows); 

    printf("Enter number of columns for matrix 2: "); 
    scanf("%d", &m2_cols); 

    //allocate memory for matrix 1 m1 
    m1 = (double **) calloc(m1_rows, sizeof(double *)); 
    for (i = 0; i < m1_rows; i++) { 
     m1[i] = (double *) calloc(m1_cols, sizeof(double)); 
    } 

    //allocate memory for matrix 2 m2 
    m2 = (double **) calloc(m2_rows, sizeof(double *)); 
    for (i = 0; i < m2_rows; i++) { 
     m2[i] = (double *) calloc(m2_cols, sizeof(double)); 
    } 

    //allocate memory for sum matrix mr 
    mr = (double **) calloc(mr_rows, sizeof(double *)); 
    for (i = 0; i < mr_rows; i++) { 
     mr[i] = (double *) calloc(mr_cols, sizeof(double)); 
    } 

    //assign mr_rows and mr_cols 
    mr_rows = m1_rows; 
    mr_cols = m2_cols; 

    //initialize product matrix 
    for (i = 0; i < m1_rows; i++) { 
     for (j = 0; j < m2_cols; j++) { 
      mr[i][j] = 0; 
     } 
    } 

    //perform matrix multiplication 
    for (i = 0; i < m1_rows; i++) { 
     for (j = 0; j < m2_cols; j++) { 
      mr[i][j] = 0; 
      for (k = 0; k < m1_cols; k++) { 
       mr[i][j] += m1[i][k] * m2[k][j]; 
      } 
     } 
    } 

    //print result 
    for (i = 0; i < mr_rows; i++) { 
     for (j = 0; j < mr_cols; j++) { 
      printf("%f\t", mr[i][j]); 
     } 
    } 

    //free memory m1 
    for (i = 0; i < m1_rows; i++); { 
     free(m1[i]); 
    } 
    free(m1); 

    //free memory m2 
    for (i = 0; i < m2_rows; i++); { 
     free(m2[i]); 
    } 
    free(m2); 

    //free memory mr 
    for (i = 0; i < mr_rows; i++); { 
     free(mr[i]); 
    } 
    free(mr); 

    return 0; 
} 

私は、セグメンテーションフォールト詳細はvalgrindのvalgrind --tool=memcheck a.outを使用して走ったが、それはそれをプリントアウトしていなかったので、結果は30000個のエラーを超えていました。

+3

GDBで実行して行を識別します。その後、修正してください。次に、30000 Valgrindエラーを修正します。その後、開発を続けます。 –

+1

@OliCharlesworth実際には、これをデバッグするためにまずコードを読むことをお勧めします。それはツールに到達するよりも常にアプローチの第一線でなければなりません。その方法は洞察につながります。 –

+0

@DavidHeffernan:おそらく30行のアプリケーションで。 seg-faultがどこで発生しているのかを調べるために、10000行のコードベースを視覚的に検査しませんでした。 –

答えて

2

mr_rowsmr_colsを割り当てていません。彼らはこのように設定する必要があります。

mr[i][j] += m1[i][k] * m2[k][j]; 

初期化されていないではない少なくともkので境界の外の要素にアクセスする:

mr_rows = m1_rows; 
mr_cols = m2_cols; 

この行は良くありません。 3つのネストされたforループ内にそのコード行が必要です。確かに、ゼロ化コードもこれに入れてください。

for(i=0; i<m1_rows; i++){ 
    for(j=0; j<m2_cols; j++){ 
     mr[i][j] = 0; 
     for(k=0; k<m1_cols; k++){ 
      mr[i][j] += m1[i][k]*m2[k][j]; 
     } 
    } 
} 

また、すべてのメモリ解放ループが間違っています。代わりに

for(i=0; i<m1_rows; i++);{ 
    free(m1[i]); 
} 
free(m1); 

のそれは浮遊セミコロンがあなたを殺したことを

for(i=0; i<m1_rows; i++){ 
    free(m1[i]); 
} 
free(m1); 

をお読みください。

m1の列の数がm2の行の数と同じであること、つまり、テストがm1_cols == m2_rowsであることを確認する必要があります。

最後の1つです。あなたはここでひどくコードを複製します。行列を割り当てるための3つの同一のforループと、割り当てを解除するための3つの同一のループはありません。これらの操作をmainから呼び出せるヘルパー関数に抽出します。

これはすべて私が見つけることができます!

+0

まだセグメント違反が発生しています。私はm2行に対してm1 colsを検査するためのテストをまだ追加していませんでしたが、m1 2x2とm2 2x2でテストしたのでうまく動作するはずです。コードを更新しました。 – manalishi

+0

あなたはそれらを使う前に 'mr_rows'と' mr_cols'に割り当てる必要があります!! –

+0

もちろん、私はメモリを割り当てる前に。ありがとう! – manalishi

1

mr_rows and mr_colsには値を割り当てていません。だから、彼らはジャンク値を持ち、コールインでメモリを割り当てるために使用します。calloc().