メモリを初期化する関数にダブルポインタを渡すと、セグメンテーションエラーが発生します。
int main()
{
double **A;
initialize(A, 10, 10);
......
}
void initialize(double **A, int r, int c)
{
A = (double **)malloc(sizeof(double *)*r);
for(int i = 0; i< r; i++) {
A[i] = (double *)malloc(sizeof(double) *c);
for(int j = 0; j < c; j++) {
A[i][j] = 0.0;
}
}
}
二重ポインタを関数に渡すにはどうすればよいですか。
ポインタートゥポインターを変更する場合は、ポインタートゥポインタートゥポインターを渡す必要があります。
void func(double ***data) { *data = malloc(sizeof(double*)*10); for.... };
double ** data; func(&data);
他の人が言ったように、あなたはあなたのinit関数でポインターを指すポインターをとる必要があります。これはinitialize
関数がどのように変化するかです:
void initialize(double ***A, int r, int c)
{
*A = (double **)malloc(sizeof(double *)*r);
for(int i = 0; i< r; i++) {
(*A)[i] = (double *)malloc(sizeof(double) *c);
for(int j = 0; j < c; j++) {
(*A)[i][j] = 0.0;
}
}
}
そしてmain
は:
int main()
{
double **A;
initialize(&A, 10, 10);
}
また、投稿したコードは、A
ポインターを渡すときにセグメンテーションフォールトを引き起こさないはずです。セグメンテーションフォールトは、関数から戻ってA
にアクセスしようとしたときに発生する可能性があります。 A
のmain
は初期化されません。そのコピーのみが初期化され、そのコピーはinitialize
関数に対してローカルであるため、戻ったときに失われます。
まず、A
内部初期化はA
内のmain
のコピーです-main
に戻ると、そのA
はまだ初期化されていません。使ってみたら-ブーム!
これをinitialize
に「参照」で渡すには、パラメーターのタイプをdouble***
に変更し、main
で&A
を渡す必要があります。次に、それをinitialize
で使用するときは、毎回逆参照する必要があります。つまり、*A
です。
メモリ不足エラーをチェックしていません。不合格。
初期化されていない値AをBY VALUEに渡して、initialize()に渡し、それを初期化します。しかしmain()に戻ると、そのローカル変数Aはまだ初期化されていません。代わりに、initialize()が_double**
_(例:A = initialize(...)
)を返すか、initialize()を変更して、最初の仮パラメーターが*pA = (double**)malloc(...);
で初期化される_double ***pA
_になるようにします。
これは、あなたがしたくない種類のことです。これに不必要にout引数を使用する代わりに、関数に割り当てて結果を返します。代わりにこれを行ってください:
int main()
{
double **A;
A = initialize(A10, 10);
}
double** initialize(int r, int c)
{
double **A;
A = malloc(sizeof(double *)*r);
for(int i = 0; i< r; i++) {
A[i] = (double *)malloc(sizeof(double) *c);
for(int j = 0; j < c; j++) {
A[i][j] = 0.0;
}
}
return A;
}