サイズを変更できる場合は2D配列はなく、intへのポインターへのポインターがあります。
配列:
int A[n][m];
Accessing the array: A[2][3] = 4; // Equivalent to *(A + 2*m + 3)
可変サイズの2D「配列」:
int **A;
A = malloc(n*m*sizeof(int));
A[2][3] = 4; // Equivalent to *A + 2*??? + 3)
コンパイラは、配列が1次元であるか、2次元であるかを認識せず、2次元のサイズを認識しません。これ以上計算することはできません。また、reallocはデータを適切な場所に配置できません。2x22Dアレイが2x32Dアレイに移行するとします。
int **A = {{0,1}, {2,3}}; // for berevity - this isn't valid C!
// stored in memory as [0,1,2,3]
A = realloc(A, 2*3* sizeof(int));
メモリに格納されている新しい配列は[0、1、、2、3、]です。これには、データをコピーする必要がありました。
2つのまともな解決策があります(それらはきれいではありませんが):1)2D配列を1D配列のリストとして扱います
int **A;
A = malloc(m*sizeof(void *));
for (i = 0; i < m; ++i) {
A[i] = malloc (n*sizeof(int);
}
(これで、reallocはこれらの配列の両方で機能するはずですが、要素にアクセスするには、ポインター演算ではなく、2つのポインター逆参照が必要になります)
2)配列の次元の1つが固定されている場合は、メモリ内の2D配列を使用して、必要に応じて再割り当てできます。
#define M 16
int **A;
A = malloc(M*n*sizeof(int)); // realloc also works
// access an element:
*(A + 3*M + 2) = 4; // (3*M is compile time constant)
この2番目の例では、常に2D配列の最後で成長します(したがって、2x2から2x3に移行する私の例は違法です。2番目の2は固定長です)。