栈与堆

来源:互联网 发布:kali linux官网 编辑:程序博客网 时间:2024/06/05 19:57

只能浅析吧  自己整理的希望有用

堆和栈
一、在了解堆和栈之前得有内存分配的相关知识:
一个由c或c++语言编译的程序 占用的内存有如下几个部分:
1、栈区:由编译器自动分配释放,存放的函数参数值,局部变量的值。对栈的操作方式相当于数据结构中的栈。
2、堆区:它和数据结构里的堆完全是两回事。一般由程序员的分配和释放,若程序员不释放,程序运行结束后可能由操作系统收回,对于堆区的分配方式类似于数据结构中的链表。
3、static全局区:全局变量和静态变量的存储是在一起的,初始化的全局变量和静态变量放在一个区域,未初始化的全局变量和未初始化的静态变量存放在相邻的一个区域。程序结束后由系统释放。
4、文字常量区:文字常量放的地方,程序结束后由系统分释放。
5、程序代码区:存放函数体的二进制代码。
二、申请方式的不同
*栈:由系统自动分配。在函数中声明一个局部变量int a, 系统将自动在栈为a开辟空间。
*堆:由程序员控制自己申请,并指明要申请的大小。在c语言中用malloc函数,而在c++中使用new运算符。
注:用new申请的内存,用delete释放。
用malloc申请的动态内存,用free释放。
三、申请后系统应答不同
*栈:只要栈的剩余空间大于所申请空间,系统就会为程序提供内存,否则系统将提示异常栈溢出。
*堆:操作系统会有一个记录空闲内存地址的链表,当系统收到程序的内存申请时,会遍历该链表,在所有节点中寻找第一个空间大于申请空间的堆节点,然后将该节点从空间结点链表中删除,并将该结点的空间分配给程序,对于大多数系统,系统会在这块内存空间中的首地址处记录本次分配的内存大小,这样,程序中的delete语句才能正确的释放本内存空间。另外,由于找到的堆节点大小不一定等于申请的内存大小,系统将会自动将多余的那部分重新放入空闲链表中。
四、申请内存大小的限制
*栈、在windows下,栈是向低地址扩展的数据结构,是一块连续的内存的区域。意思是栈顶的地址和栈的最大容量是系统先规定好的,在windows下,栈的大小在编译时就是一个确定的常数,如果申请的空间超出栈的剩余空间,将提示overflow,因此能从栈获得的空间较小。
*堆、堆是向高地址扩展的数据结构,是不连续的内存区域,这是由于系统是用链表来存储空间内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限制于计算机系统中有效的虚拟内存。所以堆获得的空间比较灵活,也比较大。
五、申请效率的不同
栈、栈是由系统自动分配,速度较快,但是程序员是无法控制的。
堆、堆是由new方法分配的内存,一般速度较慢,而且容易产生内存碎片,但是用起来比较方便。
六、堆和栈存储内容的区别
栈:在函数调用时,第一个进栈的是主函数后的下一条指令(函数调用语句的下一条可执行语句)的地址,然后是函数的各个参数,在大多数c编译器中,参数是由右向左入栈的,然后是函数中的局部变量。静态变量是不入栈的。
当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是主函数的下一条指令,程序由该点继续运行。
堆、一般是在堆的首部用一个字节存放堆的大小。而堆中的具体内容由程序员设定。
七、在数据结构方面的堆和栈,这些都是不同的概念。
*这里的堆实际上就是(满足堆性质的)优先队列的一种数据结构,第一个元素具有最高的优先权。
*这里的栈实际上就是满足先进先出性质的数据结构。




1 0