如果可以调整大小,则没有二维数组,您有一个指向 int 指针的指针。
数组:
int A[n][m];
Accessing the array: A[2][3] = 4; // Equivalent to *(A + 2*m + 3)
可变大小的二维“数组”:
int **A;
A = malloc(n*m*sizeof(int));
A[2][3] = 4; // Equivalent to *A + 2*??? + 3)
编译器不知道您的数组是一维的,还是二维的,那么二维的大小是多少。这已经无法计算了。此外,realloc 无法将数据放在正确的位置。考虑一个 2x2 2D 数组到一个 2x3 2D 数组:
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, ]; 这需要复制数据。
有两个不错的解决方案(尽管它们并不漂亮):1)将您的二维数组视为一维数组的列表
int **A;
A = malloc(m*sizeof(void *));
for (i = 0; i < m; ++i) {
A[i] = malloc (n*sizeof(int);
}
(现在 realloc 应该适用于这两个数组,但访问元素将需要两个指针取消引用而不是指针算术)
2)如果数组的维度之一是固定的,那么我们可以在内存中使用二维数组并根据需要重新分配它。
#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)
在第二个例子中,我们总是在二维数组的末尾增长(所以我从 2x2 到 2x3 的例子是非法的——第二个 2 是固定长度)。