如何为在 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 **
.
我对我的指示和参考资料感到困惑。我想在主函数中创建一个指针并将其设置为空。我想将该指针传递给另一个函数,该函数在堆上创建一个数组,填充它,并且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 **
.