演算子の優先順位が差分演算子よりも高い*arr[i]=(int*)malloc(m*sizeof(int));
ため、コードが間違っています。式では、最初に評価されてから適用されます。必要なのはその逆です(逆参照してから適用します)。[]
*
*arr[i]
arr[i]
*
arr
[]
(*arr)[i]
演算子の優先順位を上書きするには、次のような括弧を使用します。これで、コードは次のようになります。
void allocate_mem(int*** arr, int n, int m)
{
*arr = (int**)malloc(n*sizeof(int*));
for(int i=0; i<n; i++)
(*arr)[i] = (int*)malloc(m*sizeof(int));
}
上記のコードで何が起こるかをさらに理解するには、この回答を読んでください。
作業が終了したら、動的に割り当てられたメモリの割り当てを常に明示的に解除することが重要です。上記の関数によって割り当てられたメモリを解放するには、次のようにする必要があります。
void deallocate_mem(int*** arr, int n){
for (int i = 0; i < n; i++)
free((*arr)[i]);
free(*arr);
}
さらに、2D配列を作成するためのより良い方法は、以下のように1回の関数呼び出しで連続したメモリを割り当てることです。malloc()
int* allocate_mem(int*** arr, int n, int m)
{
*arr = (int**)malloc(n * sizeof(int*));
int *arr_data = malloc( n * m * sizeof(int));
for(int i=0; i<n; i++)
(*arr)[i] = arr_data + i * m ;
return arr_data; //free point
}
このメモリの割り当てを解除するには:
void deallocate_mem(int*** arr, int* arr_data){
free(arr_data);
free(*arr);
}
2番目の手法では、mallocは2回しか呼び出されないため、割り当て解除コードでは、freeはループで呼び出すのではなく、2回だけ呼び出されることに注意してください。したがって、この手法の方が優れているはずです。