区分内存中的栈和堆与数据结构中的栈和堆

首先要明确一点,这两个东西是八竿子打不着的东西,他俩没啥关系

数据结构中的栈和堆(堆栈)

首先在数据结构上要知道堆栈,尽管我们这么称呼它,但实际上堆栈是两种数据结构:堆和栈。
堆和栈都是一种数据项按序排列的数据结构。

栈就像弹夹,先装进去的最后出来,FILO(First in last out)。

堆像一棵倒过来的树,堆是一种经过排序的树形数据结构,每个结点都有一个值。通常我们所说的堆的数据结构,是指二叉堆。堆的特点是根结点的值最小(或最大),且根结点的两个子树也是一个堆。

内存中的栈和堆

1.申请方式

stack(栈区):有系统自动分配。例如:在函数中声明一个局部变量int b;系统将自动在栈区为b开辟内存空间,由系统释放。

heap(堆区):需要程序员自己申请,并指明大小,由程序员自己释放。

2.申请后系统的响应

栈:只要栈的剩余空间大于所申请的空间,系统将为程序提供内存,否则将报异常,栈溢出。

扫描二维码关注公众号,回复: 2382119 查看本文章

堆:首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到申请时,会遍历链表,寻找第一个空间大于所申请空间的堆节点,然后将该节点从空闲节点链表中删除,并将该节点的空间分配给程序,一般是在堆的头部用一个字节存放堆的大小。由于找到的堆节点的大小不一定正好等于申请的大小,系统会自动将多余的那部分重新放入空闲链表中。

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

猜你喜欢

转载自blog.csdn.net/weixin_42097765/article/details/81143915