我在初学者班上帮助教C语言。我们讨论了使用malloc进行动态内存分配,并且学生想要在malloc周围放置一个包装器。我不确定这是否有用,但玩弄东西是最好的学习方法。
然而,当学生试图通过他们的malloc包装函数为数组提供内存时,它不起作用 - 分段错误。
下面给出了一个最低限度的例子。
#include <stdlib.h>
void mallocWrapper(int *intArray, int length){
intArray = malloc(length * sizeof(int));
}
int main() {
int *array;
int arraySize = 10;
mallocWrapper(array, arraySize);
// this line causes the Segmentation fault
array[0] = 0;
return 0;
}
据我所知,数组变量只会成为内存中为数组保留的第一个点的地址。我认为无论在哪里分配内存,例如在main或mallocWrapper中,都会出现这种情况。
结果我不知道该告诉学生什么,除了我会回复他们。
任何帮助将不胜感激。谢谢
答案 0 :(得分:5)
如果要更改呼叫者的array
成员,则需要将指针传递给它。即你需要将指针传递给指向mallocWrapper
的指针。
void mallocWrapper(int **intArray, int length){
*intArray = malloc(length * sizeof(int));
}
mallocWrapper(&array, arraySize);
或者,更好的是,您可以更改mallocWrapper
以返回新分配的内存。
void* mallocWrapper(int length){
return malloc(length * sizeof(int));
}
array = mallocWrapper(arraySize);
答案 1 :(得分:1)
您正在将指针array
的 copy 传递给函数,因此函数内部的任何修改都不会反映在外部。您需要将函数的签名更改为void mallocWrapper(int **intArray, int length)
并使用*intArray = .....
才能生效。
答案 2 :(得分:1)
使用类似:
void mallocWrapper(int **intArray, int length)
{
*intArray = malloc(length * sizeof(int));
}
int main()
{
int *array = NULL; //Whenever you declare a pointer assign it to NULL
int arraySize = 10;
mallocWrapper(&array, arraySize);
array[0] = 0;
return 0;
}
答案 3 :(得分:0)
在C中,函数参数按值传递。这有助于程序的稳定性,因为在函数调用者中无意中修改变量就不那么容易了。
在您的情况下,intArray = malloc(length * sizeof(int));
不会更改array
中指针main()
的值,因此当您取消引用未初始化的指针时,您将获得未定义的行为 (通过几乎功能相同的数组表示法)。
将指针传递给指针是一种方法:
void mallocWrapper(int** intArray, int length){...
mallocWrapper(&array, arraySize);
修改函数以返回新指针。
但是,我会以这种方式阻止存根标准C库函数,因为它会使程序更难以阅读和调试:如果我看到{{{ 1}}然后我确切地知道会发生什么。如果我看到malloc
,在阅读文档或功能源代码本身之前,我不知道会发生什么。