【问题标题】:Malloc or normal array definition?malloc还是普通数组定义?
【发布时间】:2012-06-28 08:44:34
【问题描述】:

我什么时候应该在 C 中使用 malloc 而不是普通的数组定义?

我无法理解两者之间的区别:

int a[3]={1,2,3}
int array[sizeof(a)/sizeof(int)]

和:

array=(int *)malloc(sizeof(int)*sizeof(a));

【问题讨论】:

    标签: c arrays malloc


    【解决方案1】:

    一般来说,在以下情况下使用malloc():

    • 数组太大,无法放入堆栈
    • 数组的生命周期必须超过创建它的范围

    否则,使用堆栈分配的数组。

    【讨论】:

      【解决方案2】:
      int a[3]={1,2,3}
      int array[sizeof(a)/sizeof(int)]
      

      如果用作局部变量,a 和 array 都将在堆栈上分配。堆栈分配有利有弊:

      • 亲:它非常快 - 只需一次寄存器减法操作即可创建堆栈空间,并且只需一次寄存器加法操作即可将其回收
      • 缺点:堆栈大小通常是有限的(并且在 Windows 上的链接时也固定)

      在这两种情况下,每个数组中的元素数量都是编译时常量:3 显然是一个常量,而 sizeof(a)/sizeof(int) 可以在编译时计算,因为 a 的大小和 @ 的大小987654327@ 在声明 array 时是已知的。

      当元素的数量仅在运行时已知或数组的大小太大而无法安全地放入堆栈空间时,则使用堆分配:

      array=(int *)malloc(sizeof(int)*sizeof(a));
      

      正如已经指出的,这应该是malloc(sizeof(a)),因为a 的大小已经是它占用的字节数,而不是元素的数量,因此不需要额外乘以sizeof(int)。

      堆分配和释放是相对昂贵的操作(与堆栈分配相比),这应该仔细权衡它提供的好处,例如在紧密循环中被多次调用的代码中。

      现代 C 编译器支持 C 标准的 C99 版本,该版本引入了所谓的可变长度数组(或 VLA),它类似于其他语言中可用的类似功能。 VLA 的大小是在运行时指定的,如下例所示:

      void func(int n)
      {
         int array[n];
         ...
      }
      

      array 仍然在堆栈上分配,就好像数组的内存已通过调用 alloca(3) 分配。

      【讨论】:

        【解决方案3】:

        如果您不希望数组具有固定大小,您肯定必须使用 ma​​lloc()。根据您要执行的操作,您可能事先不知道给定任务需要多少内存,或者您可能需要在运行时动态调整数组大小,例如,如果有更多数据,您可能会扩大它进来。后者可以使用 realloc() 完成而不会丢失数据。

        您应该初始化一个指向整数的指针,而不是像原始帖子中那样初始化数组。

        int* array; // this variable will just contain the addresse of an integer sized block in memory
        int length = 5; // how long do you want your array to be;
        
        array = malloc(sizeof(int) * length); // this allocates the memory needed for your array and sets the pointer created above to first block of that region;
        
        int newLength = 10;
        array = realloc(array, sizeof(int) * newLength); // increase the size of the array while leaving its contents intact;
        

        【讨论】:

          【解决方案4】:

          你的代码很奇怪。

          标题中问题的答案可能类似于“当您需要相当少量的短期数据时使用自动分配的数组,使用malloc() 进行其他任何事情的堆分配”。但是很难确定一个确切的答案,这在很大程度上取决于具体情况。

          不知道为什么首先显示一个数组,然后是另一个尝试从第一个数组计算其长度的数组,最后是一个尝试执行相同操作的 malloc() 调用。

          通常您知道所需元素的数量,而不是您想要模仿其大小的现有数组。

          第二行更好:

          int array[sizeof a / sizeof *a];
          

          无需重复依赖a的类型,上面将array定义为int的数组,元素个数与数组a相同。请注意,这仅在 a 确实是一个数组时才有效。

          另外,第三行应该是:

          array = malloc(sizeof a);
          

          对于sizeof 参数和no need to cast malloc()'s return value,无需太聪明(尤其是因为你弄错了)。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2018-06-09
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-10-21
            • 2019-02-24
            • 2012-12-13
            相关资源
            最近更新 更多