【问题标题】:when should i use Dynamic memory allocation?我什么时候应该使用动态内存分配?
【发布时间】:2020-09-26 07:45:34
【问题描述】:

我正在学习 C 语言中的 malloccallocfreerealloc,但我不知道什么时候应该使用这些函数。

例如:如果我想在 C 中创建一个创建数组的程序,并且它的大小由用户输入确定:

   int n;
   printf("Enter THe Number of element in Array:..\n");
   scanf("%d",&n);
   int x[n];
   for(int i = 0 ; i < n ; i++)
   {

       x[i] = i+ 1;
   }
      for(int y = 0 ; y < n ; y++)
   {

       printf("%d\n",x[y]);
   }

输出:

Enter THe Number of element in Array:..
5
1
2
3
4
5

所以我在这里创建了这个程序,没有使用动态内存分配,这让事情变得更复杂。

【问题讨论】:

  • 只有在运行时才知道内存块的大小时,您应该使用动态内存分配(通常,因为它取决于用户输入,这可能因一次执行而异)。
  • 您的int x[n] 示例称为VLA(可变长度数组),C 的原始标准(以及C++ 的每个标准)都不支持它。
  • @goodvibration,我不明白你的意思。
  • 哪一部分?....
  • @goodvibration 例如 C++。帕斯卡和 ADA 呢?

标签: c pointers


【解决方案1】:

您的示例使用了一种称为可变长度数组的东西,它在某些情况下可以替代动态内存。但是,并非所有版本的 C 都支持 VLA(它们在 1999 年修订版中首次引入,并在 2011 年修订版中成为可选),它们不能是 structunion 类型的成员,也不能用作“全局变量”在文件范围内。与固定大小的数组一样,一旦您退出其封闭范围(即块或函数),它们的存储就会被释放。它们通常不能任意大。

您将在以下情况下使用动态内存(malloccallocrealloc):

  • 您需要分配一个块内存;
  • 您需要能够扩大或缩小该内存;
  • 您需要该内存在分配它的函数的生命周期之后持续存在;

【讨论】:

    【解决方案2】:

    堆通常比用于容纳自动变量的区域和静态存储区域(全局变量)大得多。

    所以你可以在以下情况下使用动态分配:

    1. 你需要分配内存,使用后释放
    2. 当您需要更改分配的内存大小时。
    3. 当您需要将在一个任务/函数中分配然后传递给另一个任务/函数并在作用域终止后使用的内存时
    4. 您需要分配一大块内存。

    但在你的例子中

    int x[n];
    

    不是动态分配。您只需分配具有大小设置运行时的自动数组。你不能改变它的大小,当你退出作用域时你也不能使用它,因为它的生命周期绑定到它定义的作用域。

    【讨论】:

      【解决方案3】:

      一个(实际上很常见)情况是,如果该内存是在从其他地方,因为当该函数返回时,该内存将被重置 - 或“丢失”。

      在这种情况下,您需要使用malloc(或相关)调用动态分配内存(在堆上)。这样分配的内存将是“全局的”,并且可以被程序的任何其他部分访问(只要它有指针),直到它被显式释放通过调用free() 函数。

      这是一个例子:

      #include <stdio.h>
      #include <stdlib.h>
      
      int* newArray(int n)
      {
      //  int x[n]; // Won't work: This is local (stack) memory that is lost on return
          int* x = malloc(n * sizeof(int)); // Works: This is global (heap) memory
          return x;
      }
      
      int main()
      {
          int n;
          printf("Enter The Number of Elements in Array: ");
          scanf("%d", &n);
          int* x = newArray(n);
          for (int i = 0; i < n; i++) {
              x[i] = i + 1;
          }
          for (int y = 0; y < n; y++) {
              printf("%d\n", x[y]);
          }
          free(x); // You MUST free memory that you've allocated with malloc
          return 0;
      }
      

      (您可以尝试取消注释“不会工作”行并注释掉“工作”行,自己看看。)

      【讨论】:

      • 不是“无效的”。它结束了它的生命。
      • 自动变量的放置位置取决于实现。它不必是堆栈。而且它实际上根本不重要。
      • 它不一定是函数godbolt.org/z/_6MBBS我没有退出函数有一个UB
      • @P__J__ 不,它没有必须在函数中,但我给出的示例是关于它何时 在函数中。只是一个的例子。您的链接代码是一个不同的示例。
      • @P__J__ 你能说出一个不将自动变量放入堆栈(某种堆栈)的实现,还是那纯粹是无关紧要的评论?我相信自 Algol60 以来,即 60 多年以来,如果自动变量在内存中(它们必须在这里,因为它们的地址正在被占用),它们就已经在堆栈上。
      【解决方案4】:

      您可以使用动态内存分配在运行时分配变量,并且您应该遵循一些步骤来使用它来分配内存

       int* x = malloc(n * sizeof(int)); 
      

      并在使用后释放它

      free(x); 
      

      【讨论】:

        猜你喜欢
        • 2019-07-12
        • 1970-01-01
        • 2011-08-01
        • 1970-01-01
        • 1970-01-01
        • 2015-09-27
        • 2021-09-07
        • 2012-09-22
        • 1970-01-01
        相关资源
        最近更新 更多