面试中被问到堆和栈的区别以及栈的作用,答的十分浅薄,怪不得被刷,哎,回来总结一下吧……
首先分清楚,一个编译的程序占用的内存分为以下几个部分:
1.栈区,程序运行时由编译器自动分配,结束时自动释放。存放函数的参数值,局部变量的值,返回地址值等。先进后出,函数调用时,第一个进栈的是主函数中调用后的下一条指令(函数调用语句的下一条可执行语句)的地址,然后是函数的各个参数,在大多数的C编译器中,参数是由右往左入栈的,然后是函数中的局部变量。注意静态变量是不入栈的。当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令,程序由该点继续运行。
2.堆区:在内存开辟的另一块存储区域。一般由程序员分配释放。内容由程序员自己安排。分配方式是从空闲链表中拿出一块,堆的头部用一个字节存放堆的大小,便于delete的时候能够正确释放。
3.全局区(静态存储区):编译器编译时即分配内存。全局变量和静态变量都是存储在这一块区域,初始化的全局和静态在一块区域,未初始化的全局和静态在相邻的另一块区域,程序结束后由系统释放。
4.文字常量区:常量字符串存储的位置。
5.程序代码区:程序的二进制代码存放在这里。
好了,知道他们是干什么用的,可以看一下堆与栈的区别了
1.堆是公用区域,栈是私用区域
2.堆的地址由低址到高址扩展,栈的地址由高址向低址扩展。
3.堆是由NEW分配的内存,分配比较慢,容易产生碎片;栈是由系统自动分配的,速度比较快,但是程序员无法控制。
4.申请的大小限制不一样。堆的最大限制取决于虚拟内存的大小。而栈的最大值是(vc6是1M,linux下是8M)。编译器在编译后是明确知道函数1次调用需要占多大栈内存,但不是程序递归调用N次需要占多大内存,所以一个程序总共能用的栈大小是不确定的。编译器一般允许用户设置栈的提交大小和保留大小。提交大小是指程序启动时,OS必须分配给程序的栈空间,而保留大小是表示保留一段连续地址空间给栈,便于栈的生长。而且OS在栈超出时还可能动态增大栈空间,但内存总有限制,VC6是1M,超出会出错,所以递归必须限制深度。