假设我正在传递一个指向数组的指针或一个指向函数的结构。
像
myfun1(struct node *head, int* arr, int N){
head = malloc(sizeof head);
arr = malloc(N* sizeof arr);
......
}
myfun2(struct node *head, int* arr){
...
}
我从另一个函数调用这些函数
void CallingFunction(void){
struct node* head1 = NULL;
int *arr1;
struct node* head2 = NULL;
int *arr2;
int N = 10;
head2 = malloc(sizeof head);
arr2 = malloc(N* sizeof arr);
myfunc1(head1, arr1, N);
myfunc2(head2, arr2);
}
调用函数的方法更好。myfun1
还是myfun2
?
我应该从CallingFunction或函数内部为结构和数组分配内存吗?
编辑:
正如所指出的,程序有一些错误,让我们说我纠正了这两个错误。
head = malloc(sizeof *head);
myfunc2(head2, arr2, N);
现在,答案是什么。我应该在callingFunction()或myfun()中分配内存吗。
第一个是内存泄漏(除了错误的sizeof head
和sizeof arr
)。您必须通过struct node **
来设置函数参数。
第二个更好(除了不获得arr
的大小之外):它不会隐藏内存分配,并在调用函数中正确配对malloc/free。
head = malloc(sizeof head);
是错误的,您想保留对象大小的空间,而不是指向该对象的指针大小,请更改为:
head = malloc(sizeof *head);
调用函数的方法更好。myfun1还是myfun2?
在不知道有多少元素的情况下,不能为数组保留空间,myfun2
不起作用。
这两种方法都是正确的,选择最佳选项取决于所分配块的生命周期;将内存分配和释放操作配对很重要。如果该内存只在myfun1()/myfun2()
上下文中使用,我建议在那里分配并释放它。然而,如果它将持续存在并在程序的其他部分中使用,那么最好明确内存的分配和释放位置,而不是让它成为其他操作的副作用。
此外,我建议始终使用sizeof(struct node)
和sizeof(int)
,而不是sizeof(*head)
和sizeof(*arr)
。它更加清晰,可以防止其他人在原始代码中指出的错误。
在myfun1()
的上下文中,sizeof(head)
为您提供指向结构的指针的大小,而sizeof(*head)
为您提供结构本身的大小,这正是您在本例中想要的。
同样, 对数组使用sizeof操作数还有另一个注意事项:它的行为取决于声明数组的上下文,以及它是在堆栈上还是在堆上分配的。 这里有一个小程序来举例说明这一点。在声明数组的同一上下文中使用 我的机器中该程序的输出是: 在声明/分配它们的上下文中: 在不同的上下文中: 简而言之,如果您总是将sizeof(arr)
为您提供指向int的指针的大小,sizeof(*arr)
为您提供单个intsizeof(stackArray)
时,请特别注意。#include <stdio.h>
#include <stdlib.h>
#define N 10
void aux(int *stackArray, int *heapArray) {
printf("nIn a different context:n");
printf("sizeof(*stackArray) == sizeof(int): %zun", sizeof(*stackArray));
printf("sizeof(*heapArray) == sizeof(int): %zun", sizeof(*heapArray));
printf("sizeof(stackArray) == sizeof(int *): %zun", sizeof(stackArray));
printf("sizeof(heapArray) == sizeof(int *): %zun", sizeof(heapArray));
}
int main() {
int stackArray[N];
int *heapArray = malloc(N * sizeof(int));
printf("In the context in which they were declared/allocated:n");
printf("sizeof(*stackArray) == sizeof(int): %zun", sizeof(*stackArray));
printf("sizeof(*heapArray) == sizeof(int): %zun", sizeof(*heapArray));
printf("sizeof(stackArray) == N * sizeof(int): %zun", sizeof(stackArray));
printf("sizeof(heapArray) == sizeof(int *): %zun", sizeof(heapArray));
aux(stackArray, heapArray);
free(heapArray);
return 0;
}
sizeof(*stackArray)==sizeof(int):4
sizeof(*heapArray)==sizeof(int):4
sizeof(stackArray)==N*sizeof(int):40
sizeof(heapArray)==sizeof(int*):8
sizeof(*stackArray)==sizeof(int):4
sizeof(*heapArray)==sizeof(int):4
sizeof(stackArray)==sizeof(int*):8
sizeof(heapArray)==sizeof(int*):8sizeof()
与所需的类型一起使用,而不是使用变量名,那么您就不必担心这些问题。
arr2 = malloc(N* sizeof arr);
我建议使用calloc,而不是在malloc参数中进行乘法运算:
示例:
arr2 = calloc(N, sizeof(*arr));
通常,myfunc2是首选,除非该函数是用于分配内存的包装器,在这种情况下,存在另一个用于释放内存的函数。