运行时数据区管理:
引言:
- 存储单元分配策略:
- 静态存储分配:
- 在编译时就可以完成为数据项分配存储单元
- 程序不能包含可变数组和递归调用
- 点击程序,程序先完成变量内存单元的分配,到了运行到那一步的时候直接使用编译时指定的地址
- 动态存储分配:
- 到运行时才进行存储分配
- 可以使用可变数组和递归
- 分配方式:
- 栈式存储分配
- 每进入一个过程,就为过程分配一块数据区
- 堆式存储分配
- 由用户动态申请和释放空间
- 栈式存储分配
- 静态存储分配:
- 栈式存储管理:
运行递归调用,不允许定义嵌套过程和可变数组- 嵌套过程:
在一个过程中,定义另一个过程 - 栈式存储分配:
每进入一个过程,就在栈顶建立这个过程的数据区
- 嵌套过程:
c语言栈博客:关于栈的具体内容可以到另外的博客查看
https://blog.csdn.net/ychychych1/article/details/114918778
c语言堆博客:还未整理
嵌套过程栈式存储管理:
- 特点:允许过程嵌套和递归调用
嵌套过程就是在一个函数中定义另外一个函数,且里层函数可以使用外层函数的局部变量
内层定义的函数需要知道外层的活动区域,这样就可以引用到外层函数定义的变量了
直系外层:被哪个过程包含
上图中的,main定义了p函数,那么当调用p函数时,需要记录下main函数的活动区域和自身的活动区域;在p函数中定义了q函数,所以在调用q函数时,q函数需要记录下main,p和自己的活动空间
通过这样的一张表,我们就可以知道外层函数活动空间,再到符号表查找相应的变量,得到值
d存放的是p的display表,通过查找d+k,k表示使用的是第几层,x表示的是使用的变量的偏移,得到的在R2中的就是这个变量的地址。
进入p1过程,需要记录直接外层p0和自己的活动区域
进入p2过程,需要记录直接外层p0,p1和自己的活动区域
当发生了同层调用,如上图,p2需要记录的只有p0和自己,不需要记录p1,只需要在p2的display表抄一项,在和自己的活动区域地址构成自己的display表
在调用过程中p3抄录的是p1的display表,但是在代码中,却使用p2的变量,所以这样是不允许的
堆式存储管理:
利用率不高,内部碎片(分出去但是用不到的区域)
继续使用会形成碎片,外部碎片(大小不够,导致不能组成需要的大小)
第一种方法利于让碎片的分布较散,不会像每次从头开始那样导致那样,碎片分布集中