与函数内部的动态分配有关,大多数问题&答案基于双指针。
但我被建议避免使用双指针,除非我必须,所以我想分配一个'数组指针'(不是'指针数组'),并隐藏在一个函数中。
int (*arr1d) = calloc(dim1, sizeof(*arr1d));
int (*arr2d)[dim2] = calloc(dim1, sizeof(*arr2d));
由于以上几行是典型的数组指针动态分配,所以我尝试了以下操作:
#include <stdio.h>
#include <stdlib.h>
int allocateArray1D(int n, int **arr) {
*arr = calloc(n, sizeof(*arr));
for (int i = 0; i < n; i++) {
(*arr)[i] = i;
}
return 0;
}
int allocateArray2D(int nx, int ny, int *(*arr)[ny]) {
*arr[ny] = calloc(nx, sizeof(*arr));
for (int i = 0; i < nx; i++) {
for (int j = 0; j < ny; j++) {
(*arr)[i][j] = 10 * i + j;
}
}
return 0;
}
int main() {
int nx = 3;
int ny = 2;
int *arr1d = NULL; // (1)
allocateArray1D(nx, &arr1d);
int(*arr2d)[ny] = NULL; // (2)
allocateArray2D(nx, ny, &arr2d);
for (int i = 0; i < nx; i++) {
printf("arr1d[%d] = %d n", i, arr1d[i]);
}
printf("n");
printf("arr2d n");
for (int i = 0; i < nx; i++) {
for (int j = 0; j < ny; j++) {
printf(" %d ", arr2d[i][j]);
}
printf("n");
}
return 0;
}
错误信息已经在编译过程中出现。
03.c(32): warning #167: argument of type "int (**)[ny]" is incompatible with parameter of type "int *(*)[*]"
allocateArray2D(nx, ny, &arr2d);
^
从错误消息中可以明显看出,它与参数类型(我写为int *(*arr)[ny]
)混淆了,但是我应该把什么放在那里?我尝试了一些变体,如int *((*arr)[ny])
,但没有工作)。
如果我删除2D部分,那么代码很好地编译,并按预期运行。但我想知道这是否是正确的做法,至少对于1D情况,因为有很多例子中代码的行为如预期的,但实际上有错误或不标准的行。
同样,上面的代码从一开始就不能令人满意。我甚至想删除main()中标记为(1)和(2)的行。
所以最后我想要一个类似这样的代码,但是都是用'数组指针'。
int **arr2d;
allocateArray2D(nx, ny, arr2d);
这是怎么做到的?
需要通过引用传递数组指针(不能将数组指针传递给int*
的数组):int *(*arr)[ny]
->int (**arr)[ny]
函数变为:
int allocateArray2D(int nx, int ny, int (**arr)[ny]) {
*arr = calloc(nx, sizeof(int[ny])); // or sizeof(**arr)
for (int i = 0; i < nx; i++) {
for (int j = 0; j < ny; j++) {
(*arr)[i][j] = 10 * i + j;
}
}
return 0;
}
有关详细信息,请查看正确分配多维数组
使用malloc族的最佳实践是总是检查分配是否成功,并且总是在程序结束时使用free()
。
作为微优化,我更推荐使用*arr = malloc( sizeof(int[nx][ny]) );
,因为calloc
只会以零初始化的形式产生无意义的开销膨胀。这里没有使用它,因为每个项都是显式赋值的。
- 参数类型错误 <
- 奇怪分配/gh>
- 尺寸类型错误
- 我会返回数组作为
void *
太(至少检查如果分配没有失败)。
void *allocateArray2D(size_t nx, size_t ny, int (**arr)[ny]) {
//*arr = calloc(nx, sizeof(**arr)); calloc is not needed here as you assign values to the array
*arr = malloc(nx * sizeof(**arr));
for (size_t i = 0; i < nx; i++) {
for (size_t j = 0; j < ny; j++) {
(*arr)[i][j] = 10 * i + j;
}
}
return *arr;
}