关于程序运行时的数据结构
来源:互联网 发布:淘宝宝贝突然被删除 编辑:程序博客网 时间:2024/06/05 15:26
对于可执行文件,它包含了许多的段,例如(数据段,文本段,BSS段等),它们是二进制文件中简单的区域,里面保存了和某种特定类型(如符号表条目)相关的所有信息。
对于一个源文件,哪些地方会放到哪个段,如下图:
可得知,程序代码是存放在文本段,初始化的全局变量和静态变量是存放到数据段中的,而没有初始化的全局变量和静态变量则是存放到BSS,运行时所需要的BSS段的大小记录在目标文件中,但BSS段并不占据目标文件的任何空间,局部变量、临时数据、传递到函数中的参数则是存储于栈中,而通过函数调用malloc动态分配的内存则是在堆中。对于数组的初始化,初始化所用的数据则是放在只读数据段。const修饰的变量也是存放在只读数据段。
而对于一个可执行程序,它的段在内存分布(进程的地址空间)如下:
在上图中,注意虚拟地址空间的最低部分未被映射,它位于进程的地址空间内,但并未赋予物理地址,所以任何对它的引用都是非法的,该段空间用于捕捉使用空指针和小整型值的指针引用内存的情况。
通过编写程序加深理解:
#include <stdio.h>#define ARRAY_SUM 50char global_var_data = 'A'; //存放在数据段 char global_var_bss; //存放在BSS段 int main(void){ static char static_var_data = 'A'; //存放在数据段 static char static_var_bss; //存放在BSS段 char stack_var_char; //存放在栈中 char rodata_var_array_char[ARRAY_SUM] = "I AM IN RODATA"; //数组变量stack_var_array位于栈,但字符串常量则位于只读数据段 int rodata_var_array_int[ARRAY_SUM] = {1, 2, 3, 4}; //常量1,2,3,4,0,0...这些都存储在只读数据段 int *heap_var_int = malloc(100); //存放在堆中 char *heap_var_char = malloc(100); //存放在堆中 printf ("global_var_data = %p 存放在数据段\n", &global_var_data); printf ("static_var_data = %p 存放在数据段\n", &static_var_data); printf ("global_var_bss = %p 存放在BSS段\n", &global_var_bss); printf ("static_var_bss = %p 存放在BSS段\n", &static_var_bss); printf ("heap_var_int = %p 存放在堆中\n", heap_var_int); printf ("heap_var_char = %p 存放在堆中\n", heap_var_char); printf ("stack_var_char = %p 存放在栈中\n", &stack_var_char); printf ("rodata_var_array_char = %p 存放在栈中\n", rodata_var_array_char); printf ("rodata_var_array_int = %p 存放在栈中\n", rodata_var_array_int); printf ("\"I AM IN RODATA\" = %p 存放在只读数据段\n", "I AM IN RODATA"); free(heap_var_int); free(heap_var_char); return 0;}
运行结果打印如下:
当考虑到共享库时,进程的地址空间则变成下图所示:
在进行函数调用时,堆栈存储与此有关的一些维护性信息,这些信息称为堆栈结构,或称为过程活动记录。运行时系统维护一个指针(常常位于寄存器中),通常称为fp,用于提示活动堆栈结构。它的值是最靠近堆栈顶部的过程活动记录的地址。对于过程活动记录,它的描述可以见下图:
这里所描述的静态链接是指 指向它的外层函数的活动记录指针,它允许内层过程访问外层过程的活动记录,因此也可以访问外层过程的局部数据。但这仅限于允许函数在函数内部定义的语言当中,而C语言是不允许函数在函数内部定义的,所以它的活动记录中不需要静态链接。
下面是每个函数调用在运行时创建过程活动记录的过程:
但在某些编译器中,可能会把过程活动记录的内容放到寄存器中,这样可以提高函数调用的速度。
- 关于程序运行时的数据结构
- C 程序运行时的数据结构
- 《C专家编程》:C程序运行时的数据结构(六)
- 关于C程序运行时的内存 的一些理解
- 关于程序运行时加载动态库失败的解决方法
- C++与python中关于程序运行时的计量
- C语言:关于程序运行时的内存管理
- 关于程序运行时加载动态库失败的解决方法
- 关于 windows 程序运行的几个要点
- 关于java程序的运行方式.
- 关于多媒体程序运行速度的研究
- 关于多媒体程序运行速度的研究
- 关于程序运行的堆栈结构
- 关于程序运行的堆栈结构
- 关于ios程序的后台运行
- 关于ios程序的后台运行
- 关于ios程序的后台运行
- 关于程序运行与堆栈的知识
- 使用Spring中的jdbcTemplate
- linux shell判断程序是否运行,没有运行则运行程序
- C++实现读取特定路径下文件夹及文件名的方法
- HDU 3652B-number 数位dp
- layer.js 弹出层提交form表单,action重定向
- 关于程序运行时的数据结构
- LeetCode代码分析——6. ZigZag Conversion
- NYOJ 喷水装置(二)(区间覆盖)
- HTML5标签二
- Linux下使Shell 命令脱离终端在后台运行
- C语言宏定义函数与函数的区别
- 重用字体字号对照
- myclipse的使用及其数据库的连接
- JAVA回调机制(CallBack)详解