5

次のコードセグメントのフォルトがなぜ私に説明されていますか?参照によってメモリを割り当てるのに問題はありませんが、何かを割り当てようとするか、または参照で解放するとすぐに、segfaultが発生します。Cでの参照による2D動的配列の割り振りと引き渡し

ポインタについての基本的な考え方が不足していると確信しています。

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

void allocateMatrix(float ***); 
void fillMatrix(float ***); 
void freeMatrix(float **); 

int main() { 
    float **matrix; 

    allocateMatrix(&matrix);  // this function calls and returns OK 
    fillMatrix(&matrix);   // this function will segfault 
    freeMatrix(matrix);    // this function will segfault 

    exit(0); 
} 

void allocateMatrix(float ***m) { 
    int i; 
    m = malloc(2*sizeof(float*)); 
    for (i = 0; i < 2; i++) { 
     m[i] = malloc(2*sizeof(float)); 
    } 
    return; 
} 

void fillMatrix(float ***m) { 
    int i,j; 
    for (i = 0; i < 2; i++) { 
     for (j = 0; j < 2; j++) { 
      (*m)[i][j] = 1.0;  // SEGFAULT 
     } 
    } 
    return; 
} 

void freeMatrix(float **m) { 
    int i; 
    for (i = 0; i < 2; i++) { 
     free(m[i]);     // SEGFAULT 
    } 
    free(m); 
    return; 
} 
+0

私は実際に少しはそれがコンパイル驚いて。 "void allocateMatrix(&m)"は浮動小数点数としてmを期待通りにタイプしていない可能性があります。また、C++と同じ方法でC内に参照がありません。 – Corbin

+0

なぜ、 'freeMatrix'などのシグネチャが宣言と定義で違うのですか? – keety

+0

ケビン、コービン:申し訳ありませんコピー貼り付け失敗、固定 – holocron

答えて

8

ワンセットを扱う

void allocateMatrix float ***m 
void fillMatrix float ***m 
void freeMatrix float ***m 

ここにある:

void allocateMatrix(float ***m) { 
    int i; 
    m = malloc(2*sizeof(float*)); 
    for (i = 0; i < 2; i++) { 
     m[i] = malloc(2*sizeof(float)); 
    } 
    return; 
} 

呼び出しコードに情報を戻すには、*mに割り当てる必要があります。また、ループ内で(*m)[i]に割り当てる必要があります。

void allocateMatrix(float ***m) 
{ 
    *m = malloc(2*sizeof(float*)); 
    for (int i = 0; i < 2; i++) 
     (*m)[i] = malloc(2*sizeof(float)); 
} 

他の機能が正常である可能性があります。 fillMatrix()が書かれており、それがポインタから*第三を失うことによって単純化することができますが、正しく起動されます

void fillMatrix(float **m) 
{ 
    for (int i = 0; i < 2; i++) 
    { 
     for (int j = 0; j < 2; j++) 
      m[i][j] = 1.0;   
    } 
} 

は、あなたが、ポインタをゼロにすることができるようにfreeMatrix()にトリプルポインタを渡すことをお勧めかもしれません関数呼び出し:

void freeMatrix(float ***m) 
{ 
    for (int i = 0; i < 2; i++) 
     free((*m)[i]); 
    free(*m); 
    *m = 0; 
} 

、その後の呼び出しは次のようになります。

allocateMatrix(&matrix); 
fillMatrix(matrix); 
freeMatrix(&matrix); 
+0

ありがとうジョナサン、これは完璧な意味があります。 – holocron

3

間接参照を使用してください。フォーマットとの一貫性を保つようにしてください。読みやすさを向上させ、エラーを減らします。例えば

関数が呼び出されます:

allocateMatrix &matrix 
    fillMatrix &matrix 
    freeMatrix &matrix 

宣言の問題の

(*m)[i] = malloc(2 * sizeof(float)) 
    (*m)[i][j] = 1.0 
    free (*m)[i] 
+0

これは意味がある、私は今実装しようとします。 – holocron

0

あなたの楽しみからポインタを返しますctionは、おそらくメモリを割り当てるためのより良い方法です:

float **allocateMatrix() { 
    int i; 
    float **m; 

    m = malloc(2*sizeof(float *)); 
    for (i = 0; i < 2; i++) { 
     m[i] = malloc(2*sizeof(float)); 
    } 

    return m; 
} 

int main() { 
    float **m; 

    m = allocateMatrix(); 

    /* do other things 
     fillMatrix(matrix); 
     freeMatrix(&matrix); 
    */ 
} 
関連する問題