首页 文章

静态内存分配和动态内存分配之间的区别

提问于
浏览
65

我想知道静态内存分配和动态内存分配有什么区别?

你能用任何一个例子解释一下吗?

7 回答

  • 3

    Dynamic Memory allocation - 在堆中的运行时分配内存 . 当内存的数量(大小)可变并且仅在运行时知道时使用 . 动态分配是使用某些函数实现的,例如malloc(),calloc(),realloc(),C中的free和C中的"new","delete" .

    Static Memory Allocation - 在编译时在堆栈或其他数据段中分配的内存 . 当内存量(大小)为静态/常量且在编译期间已知时使用 .

  • 90

    分配有三种类型 - 静态,自动和动态 .

    Static Allocation 表示在程序启动时分配变量的内存 . 创建程序时,大小是固定的 . 它适用于全局变量,文件范围变量以及在函数内部定义的 static 限定的变量 .

    Automatic memory allocation 出现在函数内部定义的(非静态)变量中,并且通常存储在堆栈中(尽管C标准并未强制要求使用堆栈) . 您不必使用它们来保留额外的内存,但另一方面,也限制了对此内存的生命周期的控制 . 例如:函数中的自动变量仅在函数完成之前存在 .

    void func() {
        int i; /* `i` only exists during `func` */
    }
    

    Dynamic memory allocation 有点不同 . 您现在可以控制这些内存位置的确切大小和生命周期 . 如果你没有遇到内存泄漏,这可能会导致应用程序崩溃,因为在某些时候,系统无法分配更多内存 .

    int* func() {
        int* mem = malloc(1024);
        return mem;
    }
    
    int* mem = func(); /* still accessible */
    

    在上面的示例中,即使函数终止,分配的内存仍然有效且可访问 . 完成内存后,你必须释放它:

    free(mem);
    
  • 66

    这是一个标准的面试问题:

    动态内存分配

    是在运行时使用 calloc()malloc() 和朋友分配的内存 . 它有时也被称为'heap'内存,尽管它与堆数据结构ref无关 .

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

    堆内存是持久的,直到调用 free() . 换句话说,您可以控制变量的生命周期 .

    自动内存分配

    这就是通常所说的'stack'内存,并在您输入新范围时分配(通常在调用堆栈上推送新函数时) . 移出作用域后,自动内存地址的值是未定义的,它是error to access them .

    int a = 43;
    

    请注意,范围不一定意味着功能 . 范围可以嵌套在函数中,并且变量仅在声明它的块内是范围内的 . 另请注意,未指定分配此内存的位置 . (在一个理智的系统上,它将在堆栈上,或注册优化)

    静态内存分配

    在编译时分配,静态内存中变量的生命周期是lifetime of the program .

    在C中,可以使用 static 关键字分配静态内存 . 范围仅是编译单元 .

    事情变得更有趣when the extern keyword is considered . 定义 extern 变量时,编译器会为其分配内存 . 声明 extern 变量时,编译器要求在其他地方定义变量 . 未能声明/定义 extern 变量将导致链接问题,而未声明/定义 static 变量将导致编译问题 .

    在文件范围内,static关键字是可选的(在函数之外):

    int a = 32;
    

    但不是在函数范围内(函数内部):

    static int a = 32;
    

    从技术上讲, externstatic 是C中两个独立的变量类 .

    extern int a; /* Declaration */
    int a; /* Definition */
    

    寄存器内存

    最后一个内存类是'register'变量 . 正如所料,寄存器变量应该在CPU的寄存器中分配,但实际上决定是由编译器决定的 . 您不能使用address-of将寄存器变量转换为引用 .

    register int meaning = 42;
    printf("%p\n",&meaning); /* this is wrong and will fail at compile time. */
    

    大多数现代编译器都比你选择哪些变量放在寄存器中更聪明:)

    参考文献:

    关于静态内存分配的注意事项

    说静态内存在编译时分配有点令人困惑,特别是如果我们开始考虑编译机器和主机可能不相同或者甚至不在同一架构上 .

    认为静态内存的分配由编译器处理而不是在编译时分配可能更好 . 例如,编译器可能在编译的二进制文件中创建一个大的 data 部分,并且当程序加载到内存中时,程序的 data 段中的地址将用作分配的内存的位置 . 如果使用大量静态内存,则具有使编译的二进制文件非常大的明显缺点 . 可以编写一个由不到六行代码生成的数十亿字节二进制文件 . 另一种选择是编译器注入将分配的初始化代码在程序执行之前以其他方式存储 . 此代码将根据目标平台和操作系统而有所不同 . 实际上,现代编译器使用启发式方法来决定使用哪些选项 . 您可以通过编写一个小型C程序来自己尝试,该程序可以分配10k,1m,10m,100m,1G或10G项目的大型静态数组 . 对于许多编译器,二进制大小将随着数组的大小而线性增长,并且经过某一点,当编译器使用另一个分配策略时,它将再次缩小 .

  • 2

    Static memory allocation: 编译器为声明的变量分配所需的内存空间 . 通过使用运算符的地址,获取保留的地址,并将此地址分配给指针变量 . 因为大多数声明的变量都有静态内存,这种分配方式指针变量的指针值称为静态内存分配 . 在编译期间分配内存 .

    Dynamic memory allocation: 它使用诸如malloc()或calloc()之类的函数来动态获取内存 . 如果这些函数用于动态获取内存,并且这些函数返回的值被赋予指针变量,则这种赋值称为动态内存分配.memory在运行期间得到保证 .

  • 1

    静态内存分配 . 分配的内存将在堆栈中 .

    int a[10];
    

    动态内存分配 . 分配的内存将在堆中 .

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

    因为C中没有垃圾收集器(GC),后者应该是 free d .

    free(a);
    
  • 1

    STATIC MEMORY ALLOCATIONDYNAMIC MEMORY ALLOCATION 之间的区别

    在程序执行开始之前(编译期间)分配内存 .
    在程序执行期间分配内存 .

    执行期间不执行内存分配或释放操作 .
    内存绑定在执行期间 Build 并销毁 .

    变量保持永久分配 .
    仅在程序单元处于活动状态时分配 .

    使用堆栈和堆实现 .
    使用数据段实现 .

    访问变量需要指针 .
    不需要动态分配指针 .

    执行速度比动态更快 .
    执行速度比静态慢 .

    需要更多内存空间 .
    需要更少的内存空间 .

  • 0

    静态内存分配在编译期间执行pf程序之前分配内存 . 动态内存分配是在运行时执行程序期间的内存 .

相关问题