C 在函数内分配"数组指针"

  • 本文关键字:数组 指针 分配 函数 c
  • 更新时间 :
  • 英文 :


与函数内部的动态分配有关,大多数问题&答案基于双指针。

但我被建议避免使用双指针,除非我必须,所以我想分配一个'数组指针'(不是'指针数组'),并隐藏在一个函数中。

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只会以零初始化的形式产生无意义的开销膨胀。这里没有使用它,因为每个项都是显式赋值的。

  1. 参数类型错误
  2. <
  3. 奇怪分配/gh>
  4. 尺寸类型错误
  5. 我会返回数组作为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;
}

最新更新