0

これは、パラメーターで指定されたサイズのマトリックスにスペースを割り当て、そのマトリックスへのポインターを返す私のコードです。

int **allocateSpace(int row, int col){  
   int i;
   int **a;
   a = malloc(sizeof(int *) * row);
   for(i = 0; i < row; i ++)                                               
      a[i] = malloc(sizeof(int) * col);  
   return a;
}      

上記のコードは意図したとおりに機能します。

ただし、コードを次の形式に変更すると、セグメンテーション違反が発生します。

void allocateSpace(int **a, int row, int col){
    int i;
    a = malloc(sizeof(int *) * row);
    for(i = 0; i < row; i ++)
      a[i] = malloc(sizeof(int) * col);
}

関数から戻ったときに、allocateSpace()割り当てられたメモリが解放されたようです(セグメンテーション違反が発生したため)。しかし、なぜ?私がしているのは、特定のポインターにメモリを割り当てることだけであり、それはすべてサブ関数で行われます。

私の質問を要約すると、コードの 2 番目の部分でセグメンテーション違反が発生するのはなぜですか? どうもありがとうございました!

4

4 に答える 4

6

割り当てられたメモリを割り当てるには、ポインタをポインタに渡す必要があるため、次のようになります。

void allocateSpace(int ***a, int row, int col){
    int i;
    *a = malloc(sizeof(int *) * row);
    for(i = 0; i < row; i ++)
      ( *a )[i] = malloc(sizeof(int) * col);
}

そしてそれを呼び出すには、:のアドレスを渡す必要がありますint**

int** ppData;

allocateSpace( &ppData, 10, 10 );
于 2012-04-04T10:29:39.370 に答える
0

2番目の関数では、int ** aは値(ポインター)によって渡されるため、関数の変更が呼び出し元の関数に影響を与えることはありません。この値は参照によって渡す必要があります。

于 2012-04-04T10:33:26.563 に答える
0

問題は、値で渡されるポインターを変更しようとしていることです。

void allocateSpace(int **a, int row, int col){
  // ...
}

int** aここでは値で渡されます(つまり、ポインター値は関数パラメーターとして使用するためにスタックにコピーされます)。

あなたがするとき

a = malloc(sizeof(int *) * row);

ポインターのコピーのみを変更し、関数が戻ると、変更は破棄されます。

解決策は、ポインターを参照渡しすることです。つまり、

void allocateSpace(int ***a, int row, int col){
//...
}

参照に従って実際の値を変更します。

*a = malloc(sizeof(int *) * row);
于 2012-04-04T10:32:14.710 に答える
0

2 番目のケースでは、関数のパラメーターを変更aしています。これは、値によって渡されたローカル コピーです。そのため、次のような関数を呼び出した場合allocateSpace(myptr,N,M)myptrは変更されません。関数のローカル コピーが変更されます。したがって、myptr呼び出しの前に含まれていたものは何でも含まれます - おそらくゴミです。関数の param を次のように変更する必要があります: int ***a(なんてこった) そして、関数本体の*各参照の前に (逆参照 op) を追加します。a

これを、関数内の単純な int を変更したい状況と比較してください。param は でint *、関数本体の代入は に移動する必要があり*aます。ここでも同じことが当てはまります。目標を達成するには、さらに 1 レベルの逆参照が必要です。

于 2012-04-04T10:33:04.860 に答える