首先答这个问题需要知道这个问题的重点。就是两个方面:一个从数据结构方面,一个要从操作系统中程序内存分配方面。
1.堆和栈之数据结构方向
堆
大家最熟悉数据结构中的堆就是堆排序了,想看堆排的同学可以看下我github上的这个简短代码[https://github.com/TeamWe/FOR-C/blob/master/heap.c] 。对就从这个角度下手。堆分为最大堆和最小堆。最大堆:跟节点的值大于孩子节点的值,左右子树也都是最大堆。经常用来查找最大数和最小数,面试中问一些大数据查找数值算法一般回答他就没错了!
栈
基础的数据结构有如下的几个特点
1,先入后出,后入先出。
2,除头尾节点之外,每个元素有一个前驱,一个后继。
2.操作系统方面
导言-一个linux的进程分布(可选择跳过)
从一个进程的地址空间的低地址向高地址增长
1.code段,就是存放代码,可读可执行不可写,也称为正文段,代码段。2.data段,存放已初始化的全局变量和已初始化的static变量(不管是局部static变量<这里面就包括我上篇问题提到的字符串的存储>还是全局static变量)
3.bss段,存放全局未初始化变量和未初始化的static变量(也是不区分局部还是全局static变量)
以上这3部分是确定的,也就是不同的程序,以上3部分的大小都各不相同,因程序而异,若未初始化的全局变量定义的多了,那么bss区就大点,反之则小点。
4.heap,也就是堆,堆在进程空间中是自低地址向高地址增长,你在程序中通过动态申请得到的内存空间(c为malloc\free,c++为new\delete),就是在堆中动态分配内存的。(这个详细分配,看我的malloc的底层实现)
5.stack,栈,程序中每个函数中的局部变量,都是存放在栈中,栈是自高地址向低地址增长的。起初,堆和栈之间有很大一段空间,然后随着,程序的运行,堆不断向高地址增长,栈不断向高地址增长,这样,堆跟栈之间的空间总有一个最大界限,超过这个最大界限,就会出现堆跟栈重叠,就会出错,所以一般来说,Linux下的进程都有其最大空间的。
6.再往上,也就是一个进程地址空间的顶部,存放了命令行参数和环境变量。
堆和栈
同:两者在操作系统中都是为了存储数据而存在的。
异:1.出现错误的情况:栈由编译器自动分配释放,最大的程序问题会出现栈溢出。堆由程序员手动管理稍有不当就会产生内存泄漏还有各种segment fault。
2.效率:栈申请速度快,堆要经过算法筛选比较慢。操作系统有一个记录当前空闲内存地址的链表,当系统收到程序的申请时,会遍历该链表,并且寻找第一个大于当前申请的堆空间(这取决于采取何种算法-首次适应算法,循环首次适应算法,最佳适应算法,最坏适应算法,快速适应算法),然后重新建立新的空闲链表,将这个节点分配。另一个堆慢的原因就是比如int *p = &a;他是要先在p里面找到这个指针的地址然后再到这个地址指向的空间寻找所需的数据,多了一个步骤固然变慢了。
3.内容:栈一般放当前所需要的数据,堆中随时存储。
网友评论