我们在上节中说到了栈区、堆区以及静态存储区,那么我们来看看在程序文件的一般布局。我们先来看看不同代码在可执行程序中的对应关系,如下图所示
我们看到程序中的经过初始化的全局变量和加 static 修饰的初始化过后的局部变量都放在 .data 段,未经初始化的全局变量和加 static 修饰的局部变量都放在 .bss 段,函数和函数调用都放在 .text 段。
我们下来看看程序和进程的区别,程序是静态的概念表现为一个可执行文件,而进程是动图的概念,程序由操作系统加载运行后得到进程。每个程序可以对应多个进程,但是每个进程只能对应一个程序。我们举例来说,一个浏览器就相当于是程序,它没运行就没有对应的进程。但是我们可以同时多次打开同一个浏览器,这时每个打开的浏览器就相当于是一个进程。
我们在面试中有时会遇到这样的问题:包含脚本代码的文本文件是一种类型的可执行程序吗?如果是,它对应什么样的进程呢?我们想的是脚本程序嘛,就肯定能直接运行哈,那它会对应什么样的进程呢?不知所云了。哈哈,我们来看看一般的可执行程序和脚本文件的区别,如下图所示
我们看到可执行程序是由操作系统直接加载的,便直接对应了一个进程。但是我们运行脚本文件之后,那么操作系统中会有对应的脚本解释程序,经脚本解释程序执行后,便产生对应的进程,这个进程反过来读取并解释执行脚本。这样脚本文件就得到运行啦。
下来我们来看看文件布局在内存中的映射
我们看到可执行程序 a.out 中分为头文件、.text、.data 以及 .bss 段。对应在进程中便去掉了头文件而加上了栈和堆。那么我们接下来讲讲各个段的作用,堆栈段在程序运行后才正式存在,是程序运行的基础; .bss 段存放的是未初始化的全局变量和静态变量; .text 段存放的是程序中的可执行代码; .data 段保存的是已经初始化了的全局变量和静态变量; .rodata 段存放程序中的常量值,如字符串常量。
静态存储区通常指程序中的 .bss 和 .data 段;只读存储区通常指程序中的 .rodata 段;局部变量所占空间为栈上的空间;动态空间为堆中的空间;程序可执行代码存放于 .text 段。
那么我们想下,同是全局变量和静态变量,为什么初始化的和未初始化的需要保存在不同段中呢?通常在编译器中,没有初始化的变量,我们都要初始化为 0,如果我们一个一个的去检查,是不是效率就很低呢?如果我们分开存放,那么那些已经初始化过的变量就不用去检查了,从而效率会变高。
通过对程序文件中内存布局的学习,总结如下:1、程序源码在编译后对应可执行程序中的不同存储区;2、程序和进程不同,程序是静态概念,进程是动图概念;3、堆栈段是程序运行的基础,只存在于进程空间中;4、程序可执行代码存放于 .text 段,是只读的;5、.bss 和 .data 段用于保存全局变量和静态变量。
欢迎大家一起来学习 C 语言,可以加我QQ:243343083。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。