1. 栈(stack)

栈用于存储函数(包括主函数)内部使用的变量,是一个先进先出(LIFO)结构,每次声明一个新变量,都会将其推入栈中。当函数运行结束时,栈上上与该函数所有相关的变量(称为一个栈帧)将被释放。栈由CPU自动管理,用户不必关心如何分配和释放内存。栈内存分为栈帧,每次函数调用都会为其分配一个栈帧,在函数返回时释放。

栈的大小通常有限,如果程序试图将过多的信息放入栈中,就会出现栈溢出

栈的先进后出并不是指栈中的变量是先进后出的,而是指"栈帧"的先进后出,这保证了函数的调用顺序。

  • 栈内存由CPU管理
  • 变量自动分配和释放
  • 栈的大小有限制
  • 当变量创建和销毁时,栈会增长和收缩

2. 堆(heap)

堆是一块大的内存,支持动态分配,由用户负责管理。可以通过malloc方法分配内存,通过free方法回收内存,若内存使用后没有回收,则会导致"内存泄漏",即这块内存无法被其他进程所用。

与栈不同,除物理内存大小的限制,堆的大小没有严格限制。在堆中创建的变量可在程序的任何地方访问(全局变量)。

  • 堆内存由程序员管理
  • 在C中,使用mallocfree来分配和释放堆内存
  • 需要用指针访问堆

3.

考虑以下程序

#include <stdio.h>
#include <stdlib.h>

int x;          

int main(void) 
{
    int y;   
    char *str; 

    y = 4;
    printf("stack memory: %d\n", y);

    str = malloc(100 * sizeof(char)); 
    str[0] = 'm';
    printf("heap memory: %c\n", str[0]); 
    free(str);         
    return 0;
}

在上面这段程序中,x是一个全局变量,ystr都是局部变量。mallocstr在堆上分配了100个字节的内存,free则释放了分配的这些内存。

20210623153015

参数
数据结构类型堆栈是线性数据结构。堆是一个层次数据结构。
访问速度高速访问与堆栈相比速度较慢
空间管理空间由操作系统高效管理,因此内存永远不会变得支离破碎。堆空间没有有效地使用。当内存块首先分配然后释放时,内存可能会变得支离破碎。
访问仅限本地变量它允许您在全球范围内访问变量。
空间大小限制取决于操作系统的堆栈大小限制。内存大小没有特定的限制。
调整变量无法重新缩放变量可以重新缩放。
内存分配内存被分配到一个连续块中。内存以任意随机顺序分配。
分配和交易定位通过编译器说明自动完成。它由程序员手动完成。
释放不需要去分配变量。需要明确去分配。
成本更多
实现基于简单阵列、使用动态内存和基于链接列表的 3 种方式可以实现堆栈。堆可以使用阵列和树木实现。
主要问题内存不足内存碎片
参考地区自动编译时间说明。足够
灵活性固定尺寸调整大小是可能的
访问时间更快