【问题标题】:should i allocate memory inside a function or place function has been called我应该在函数内分配内存还是调用放置函数
【发布时间】:2016-05-14 17:11:11
【问题描述】:

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

喜欢

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

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

【问题讨论】:

    标签: c function malloc


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:
      head = malloc(sizeof head);
      

      错了,你想用一个对象的大小来预留空间,而不是用指向这个对象的指针的大小,改成:

      head = malloc(sizeof *head);
      

      哪种方法调用函数更好。 myfun1 还是 myfun2 ?

      你不能在不知道有多少元素的情况下为数组保留空间,myfun2 不起作用。

      【讨论】:

      • mybad,假设我纠正了错误 head = malloc(sizeof *head);我在 myfunc2 中传递 N 。那么哪个更好呢?
      • 我不明白你,如果你将N 传递给myfun2 两个函数是相等的,不是吗?
      • 对于 myfun1(),我在 myfun1() 中分配内存,对于 myfun2(),我在 callFunction() 中分配内存。
      • 你的意思是如果将代码分成两个调用而不是使用一个大函数来完成所有任务会更好吗?那么是的,分开。
      【解决方案3】:

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

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

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

      同样,sizeof(arr) 为您提供指向 int 的指针的大小sizeof(*arr) 为您提供单个 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() 与您想要的类型而不是变量名一起使用,则您无需担心这些事情。

      【讨论】:

        【解决方案4】:
         arr2 = malloc(N* sizeof arr);
        

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

        例子:

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-10-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-05-25
          • 2019-09-23
          相关资源
          最近更新 更多