《操作系统真象还原》——0.15 局部变量和函数参数为什么要放在栈中-阿里云开发者社区

开发者社区> 开发与运维> 正文

《操作系统真象还原》——0.15 局部变量和函数参数为什么要放在栈中

简介: 局部变量,顾名思义其作用域属于局部,并不是像static那样属于全局性的。全局的变量,意味着谁都可以随时随地访问,所以其放在数据段中。而局部变量只是自己在用,放在数据段中纯属浪费空间,没有必要,故将其放在自己的栈中,随时可以清理,真正体现了局部的意义。

本节书摘来自异步社区《操作系统真象还原》一书中的第0章,第0.15节,作者:郑钢著,更多章节内容可以访问云栖社区“异步社区”公众号查看

0.15 局部变量和函数参数为什么要放在栈中

局部变量,顾名思义其作用域属于局部,并不是像static那样属于全局性的。全局的变量,意味着谁都可以随时随地访问,所以其放在数据段中。而局部变量只是自己在用,放在数据段中纯属浪费空间,没有必要,故将其放在自己的栈中,随时可以清理,真正体现了局部的意义。这个就是堆栈框架,提到了就说一点吧,栈由于是向下生长的,堆栈框架就是把esp指针提前加一个数,原esp指针到新esp指针之间的栈空间用来存储局部变量。解释一个概念,堆是程序运行过程中用于动态内存分配的内存空间,是操作系统为每个用户进程规划的,属于软件范畴。栈是处理器运行必备的内存空间,是硬件必需的,但又是由软件(操作系统)提供的。堆是堆,而堆栈就是栈,和堆没关系,只是都这么叫。栈和堆栈都是指的栈,在C程序的内存布局中,由于堆和栈的地址空间是接壤的,栈从高地址往低地址发展,堆是从低地址往高地址发展,堆和栈早晚会碰头,它们各自的大小取决于实际的使用情况,界限并不明朗,所以这可能是堆栈常放在一直称呼的原因吧。

函数参数为什么会放到栈区呢?第一也是其局部性导致的,只有这个函数用这个参数,何必将其放在数据段呢。第二,这是因为函数是在程序执行过程中调用的,属于动态的调用,编译时无法预测会何时调用及被调用的次数,函数的参数及返回值都需要内存来存储,如果是递归调用的话,参数及返回值需要的内存空间也就不确定了,这取决于递归的次数。也许这么说您也依然觉得费解,如果完全明白,需要了解一下编译原理,很多知识都是通过实践后才搞明白的。当然我不是说让您为了搞明白这个问题而去尝试写个编译器。

总之,在函数的编译阶段根本无法确定它会被调用几次,其参数和函数的返回地址也要内存来存储,所以也不知道其会需要多少内存。我想,即使神通广大的编译器设计者可以预测这些了,那提前准备好内存也是一种浪费,而且您想啊,在系统中可用内存紧缺的情况下,提前把内存分配给目前并不使用内存的进程(只因为要存储其函数参数),而眼前需要内存的程序若无内存可用,引用罗永浩老师的一句话:“我想不到比这个更伤感的事情了”所以编译器为了让世界更美好一些,选择将为函数参数动态分配内存,也就是在每次调用函数时才为它在栈中分配内存。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:
开发与运维
使用钉钉扫一扫加入圈子
+ 订阅

集结各类场景实战经验,助你开发运维畅行无忧

其他文章