在不同情境下,堆和栈代表不同的含义。一般有两层含义:(1)程序内存布景场景下,堆和栈代表的是两种内存管理方式;(2)数据结构场景下,堆和栈表示两种常用的数据结构。
1.数据内存分布中的堆与栈
栈由操作系统自动分配释放,用于存放函数的参数值、局部变量等,其操作方式类似于数据结构中的栈。堆由程序员分配释放,若程序员不分配释放,程序结束时由操作系统回收,其分配方式类似于链表。
堆上内存空间的分配过程:首先,在操作系统中有一个记录空闲内存地址的链表。当有程序动态申请空间时,会遍历该链表,寻找第一个空间大于所申请空间的节点,然后将该节点从链表中删除,并将这块空间分配给程序。另外,大多数程序会在这块内存空间的首地址中记录本次分配的大小,便于delete释放内存。
堆和栈的区别:
(1)首先给出 x86 32 位 linux 系统进程地址空间上堆和栈的描述,先是.text,.data,.bss,堆,栈,命令行参数,环境变量等,来说说在虚拟地址空间上,堆和栈的划分是完全两块不同的内存,不能混为一谈的。 Linux下4G虚拟地址空间布局:https://blog.csdn.net/PinkBananA_/article/details/96446733
(2) 栈内存是由系统分配,系统释放的;以函数为单位进行栈内存分配,函数栈帧,局部变量,形参变量等都存放在栈内存上。堆内存是由用户自己分配的, C 语言用 malloc/free进行分配释放, C++用 new/delete 进行分配释放,由于堆需要用户自己管理,因此堆内存很容易造成内存泄露,而栈内存不会。
(3)栈的内存分配释放速度快效率高,内存都是连续的;堆内存的分配释放相对于栈来说效率低一些,内存不一定连续,容易产生内存碎片,但是灵活性高。
(4)栈是由高地址向低地址扩展的连续内存,栈的大小一般为 2M 或者 10M(redhat 系统可以用 ulimit -s 命令来查看,是 10M);堆是由低地址向高地址扩展的非连续内存,堆的大小影响的因素比较多,和系统虚拟内存的大小有关系。
2.数据结构中的堆与栈
栈本身也是一种线性表,只不过是有限制的。它只允许在一端进行插入和删除操作,这一端称为栈顶,另一端为栈底。因为只能在一端进行插入和删除,因此栈具有“先进后出”的特性。
堆是一种树形结构,是一个完全二叉树。它满足所有节点的值总是不大于或不小于它的双亲节点的值,也就是说,在一个堆中,根节点是最大(大根堆)或最小节点(小根堆)。