如何为在 C 中作为参数传递的数组指针正确分配内存

How to properly allocate memory for an array pointer passed as an argument in C

我对我的指示和参考资料感到困惑。我想在主函数中创建一个指针并将其设置为空。我想将该指针传递给另一个函数,该函数在堆上创建一个数组,填充它,并且returns创建数组的大小。

我试图找到另一篇关于该主题的文章,但未能找到从函数内部分配内存的文章。下面的示例代码说明了这个概念,但我并不是在编写程序来完成任何特定任务。

int fillarray(/* pointer to an array */){

    // malloc the array to size n
    // fill array with n elements

return n;
}

int main(){

    int* array = NULL;
    int size = fillarray(/* pass the pointer by reference */);

    for(int i = 0; i < size; i++) printf("%d\n", array[i]);

    free(array);

return 0;
}

更新:

谢谢大家的评论。我学到了很多关于解决这个问题的指针。下面的代码完成了我需要的。谢谢@Lundin。您的回答使我找到了实际的解决方案。也谢谢@ssd。您的视觉帮助我对我在代码中看到的内容有了一些直觉。

int fillarray(int** array){

    *array = (int*)malloc(2 * sizeof(int));
    (*array)[0] = 0;
    (*array)[1] = 1;

return 2;
}

int main(){

    int* array = NULL;
    int size = fillarray(&array);
    for(int i = 0; i < size; i++) printf("%d\t", array[i]);

return 0;
}

严格来说C中没有"references",一切都是按值传递。尽管术语 "pass by reference" 与语言无关,实际上只是意味着将地址传递给数据。 (C++ 有一个称为引用的语言概念,但它实际上只是美化了只读指针。)

所以要实现你想要的,你必须传递指针本身的地址。这样,函数就可以访问指针并将其设置为指向新地址。因此将函数声明为 int fillarray (int**) 调用函数为 fillarray(&array)。 malloc的结果需要赋值给pointer-to-pointer指向的地方——它指向的是main()中声明变量的原始指针的地址。

至于分配可变大小,您必须为此向函数添加一个额外的纯整数​​参数。

我同意并同意 Lundin's 回答,但为了更概念化,我将在下面添加绘图,因为我在过去理解指针时有过同样的痛苦。

  • 下面的第一个整数指针(int *a)位于内存地址4c4b40并且它的值被设置为零(这意味着这个指针a被设置至 null).

  • 第二个整型指针(int *b)在内存地址4c4b48,其值设置为4c4b58(也就是说,这个指针指向内存地址 4c4b58,长度为整数)。如果该地址对应于变量 int x = 16(十六进制 10 等于 16),那么取消引用指针 b 将为您提供整数值 16(*b = 16 因为 x = 16)。

  • 第三个内存是另一个字符串指针,指向下面某处的内存地址。

返回答案:

如果您要更改第一个指针(a)的地址以指向变量x,那么函数您'调用需要接收指针的地址(不是指针本身);即 &a 而不是 a,它对应于 4c4b40。调用的函数将接收地址 4c4b40 作为内存地址,并将其值从 000000 更改为 4c4b58。当然,函数装饰将包含一个 int **;因为,如果整数指针是 int *,则指向指针的指针将是 int **.