C 什么时候应该使用动态内存分配?

C 什么时候应该使用动态内存分配?,c,pointers,C,Pointers,我正在学习C语言中的malloc、calloc、free和realloc,但我不知道什么时候应该使用这些函数 例如:如果我想用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] =

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

例如:如果我想用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]);
   }

因此,我在这里创建了这个程序,没有使用动态内存分配,这使事情对我来说更加复杂。

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

因此,您可以在以下情况下使用动态分配:

  • 您需要分配内存,并在使用后释放内存
  • 当您需要更改分配的内存大小时
  • 当您需要内存时,这些内存将在一个任务/函数中分配,然后传递给另一个任务/函数,并在作用域终止后使用
  • 您需要分配一大块内存
  • 但在你的例子中

    int x[n];
    
    不是动态分配。您只需使用运行时设置的大小分配自动数组。您不能更改它的大小,也不能在退出作用域时使用它,因为它的生存期绑定到定义它的作用域。

    一种(事实上非常常见)的情况是使用本地分配的内存(通常,但不一定,在堆栈上),就像您的示例那样,如果在从其他地方调用的函数中分配内存,则该函数将不起作用,因为当该函数返回时,该内存将被重置或“丢失”

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

    下面是一个例子:

    #包括
    #包括
    int*newArray(int n)
    {
    //int x[n];//不起作用:这是返回时丢失的本地(堆栈)内存
    int*x=malloc(n*sizeof(int));//工作:这是全局(堆)内存
    返回x;
    }
    int main()
    {
    int n;
    printf(“输入数组中的元素数:”);
    scanf(“%d”和“&n”);
    int*x=newArray(n);
    对于(int i=0;i

    (您可以尝试取消对“不起作用”行的注释,并注释掉“起作用”行,以便自己查看。)

    您可以使用动态内存分配在运行时分配变量,在需要分配内存的地方,您应该遵循一些步骤

     int* x = malloc(n * sizeof(int)); 
    
    free(x); 
    
    并在使用后使用此软件将其释放

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

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

    您可以在以下情况下使用动态内存(
    malloc
    calloc
    realloc
    ):

    • 你需要分配一大块内存
    • 你需要能够增长或收缩记忆
    • 您需要在分配该内存的函数的生命周期之外保持该内存
    当您仅在运行时知道内存块的大小时,您应该使用动态内存分配(通常,因为它取决于用户输入,用户输入可能因执行的不同而不同)。您的
    int x[n]
    示例称为VLA(可变长度数组),C的原始标准不支持它“好的振动,我不理解你。哪一部分?……好振动,例如C++ C++。Pascal和艾达怎么办?”没有“无效”。。它结束了它的生命。自动变量的放置位置取决于实现。它不必是堆栈。事实上,这一点都不重要。它不必是函数。我没有退出函数以获得UB@P__J__不,它不必在函数中,但我给出的例子是关于它在函数中的时间。只有一个例子。Y我们的链接代码是一个不同的例子。@P_uuj_uu你能说出一个没有将自动变量放在堆栈(某种堆栈)上的实现吗,或者这是一个完全不相关的评论吗?我相信自从Algol60以来,也就是说,60多年来,自动变量一直在堆栈上,如果它们在内存中的话(他们必须在这里,因为他们的地址被记录了)。