我应该在函数内部分配内存还是调用函数

时间:2016-05-14 17:11:12

标签: c function malloc

假设我将一个指向数组或结构的指针传递给函数。

喜欢

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);
 }

调用函数的方法更好。 myfun1myfun2

我应该从CallingFunction或函数内部为结构和数组分配内存吗?

编辑:

正如所指出的,程序有一些错误,让我说我纠正了这两个错误。

  head = malloc(sizeof *head);
  myfunc2(head2, arr2, N);

现在,答案是什么。我应该在callingFunction()或myfun()中分配内存。

4 个答案:

答案 0 :(得分:1)

head = malloc(sizeof head);

错误,你想要保留一个对象大小的空间,而不是指向这个对象的指针的大小,改为:

head = malloc(sizeof *head);
  

调用函数的方法更好。 myfun1或myfun2?

如果不了解有多少元素myfun2无效,则无法为数组预留空间。

答案 1 :(得分:1)

第一个是内存泄漏(除了错误的sizeof headsizeof arr)。您必须通过struct node **来设置函数参数。

第二个更好(除了没有得到arr的大小):它不会隐藏内存分配并导致在调用函数内正确配置malloc / free。

答案 2 :(得分:1)

两种方法都是正确的,选择最佳选项取决于分配块的生命周期;配对内存分配和释放操作很重要。如果该内存仅在myfun1()/myfun2()上下文中使用,我建议在那里分配和释放它。但是,如果它将持续存在并在程序的其他部分中使用,那么最好将内存分配和释放的位置变得非常明显,而不是让它成为某些其他操作的副作用。

另外,我建议您始终使用sizeof(struct node)sizeof(int)代替sizeof(*head)sizeof(*arr)。它更加清晰,可以防止其他人在原始代码中指出的错误。

myfun1()的上下文中,sizeof(head)为您提供指向结构的指针的大小,而sizeof(*head)为您提供的大小结构本身,这是你想要的情况。

同样,sizeof(arr)为您提供了指向int 的指针的大小,sizeof(*arr)为您提供了 single int 的大小。

对数组使用sizeof操作数还有一​​个警告:它的行为取决于声明数组的上下文以及它是在堆栈上还是在堆上分配的。

这是一个小例子,可以举例说明这一点。在声明数组的相同上下文中使用时,请特别注意sizeof(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): %zu\n", sizeof(*stackArray));
    printf("sizeof(*heapArray) == sizeof(int): %zu\n", sizeof(*heapArray));
    printf("sizeof(stackArray) == sizeof(int *): %zu\n", sizeof(stackArray));
    printf("sizeof(heapArray) == sizeof(int *): %zu\n", 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): %zu\n", sizeof(*stackArray));
    printf("sizeof(*heapArray) == sizeof(int): %zu\n", sizeof(*heapArray));
    printf("sizeof(stackArray) == N * sizeof(int): %zu\n", sizeof(stackArray));
    printf("sizeof(heapArray) == sizeof(int *): %zu\n", 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 *):8

简而言之,如果您总是将sizeof()与您想要的类型一起使用而不是变量名,那么您无需担心这些事情。

答案 3 :(得分:0)

 arr2 = malloc(N* sizeof arr);

我建议使用calloc而不是在malloc参数中进行乘法运算:

示例:

 arr2 = calloc(N, sizeof(*arr));

通常myfunc2是首选,除非函数是分配内容的包装器,在这种情况下,存在另一个释放内存的函数。