首先要明确一点,这两个东西是八竿子打不着的东西,他俩没啥关系
数据结构中的栈和堆(堆栈)
首先在数据结构上要知道堆栈,尽管我们这么称呼它,但实际上堆栈是两种数据结构:堆和栈。
堆和栈都是一种数据项按序排列的数据结构。
栈就像弹夹,先装进去的最后出来,FILO(First in last out)。
堆像一棵倒过来的树,堆是一种经过排序的树形数据结构,每个结点都有一个值。通常我们所说的堆的数据结构,是指二叉堆。堆的特点是根结点的值最小(或最大),且根结点的两个子树也是一个堆。
内存中的栈和堆
1.申请方式
stack(栈区):有系统自动分配。例如:在函数中声明一个局部变量int b;系统将自动在栈区为b开辟内存空间,由系统释放。
heap(堆区):需要程序员自己申请,并指明大小,由程序员自己释放。
2.申请后系统的响应
栈:只要栈的剩余空间大于所申请的空间,系统将为程序提供内存,否则将报异常,栈溢出。
堆:首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到申请时,会遍历链表,寻找第一个空间大于所申请空间的堆节点,然后将该节点从空闲节点链表中删除,并将该节点的空间分配给程序,一般是在堆的头部用一个字节存放堆的大小。由于找到的堆节点的大小不一定正好等于申请的大小,系统会自动将多余的那部分重新放入空闲链表中。
3.申请大小的限制
栈:在windows下,栈是向低地址扩展的数据结构,是一块连续的内存区域,栈的大小是2M,因此,能从栈获得的空间较小。所以用子函数还是有物理意义的。
堆:堆是向高地址扩展的数据结构,是不连续的内存区域。链表的遍历是由低地值向高地址遍历。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。
4.申请效率比较
栈:有系统自动分配,速度较快,但程序员无法控制。
堆:由malloc(),new()分配的内存,速度较慢,并且容易产生内存碎片。
5.存取效率比较
char str1[] = "aaa";
char *str2 = "bbb";
其中aaa是在运行时刻进行赋值的,存放在栈中,bbb是在编译时就确定了,放在堆中,在以后的存取中,数组(堆区)快于(指针)栈区。
int a = 0; //全局初始化区
char *p1; //全局未初始化区
int main()
{
int b; //栈
char s[] = "abc";//栈
char *p2; //栈
char *p3 = "123456"; 123456\0 //在常量区,p3 在栈区
static int c = 0; //全局(静态)初始化区
p1 = (char *)malloc(10);//堆
p2 = (char *)malloc (20);//堆
}
关于堆和栈区的比喻
使用栈就象我们去饭馆里吃饭,只管点菜(发出申请)、付钱、和吃(使用),吃饱了就走,不必理会切菜、洗菜等准备工作和洗碗、刷锅等扫尾工作,他的好处是快捷,但是自由度小。
使用堆就象是自己动手做喜欢吃的菜肴,比较麻烦,但是比较符合自己的口味,而且自由度大。比喻很形象,说的很通俗易懂。
https://blog.csdn.net/Fiorna0314/article/details/49757195
https://blog.csdn.net/wolenski/article/details/7951961#comments