一、前言
周知,c程序的执行需要有执行环境,其中一个重要的环境就是内存空间,也可以成为存储空间。本文将介绍c程序在执行前中后的存储空间布局。
二、c程序执行前
在c程序执行前,它仅是一个可执行文件存放到磁盘中,这就没有什么布局可言了。
三、c程序执行中
在c程序执行过程中,程序中的不同组成部分在内存中的存放位置是不同的,主要有如下几个部分:正文段(也叫代码段)、初始化数据段(data)、未初始化数据段(bss)、栈、堆
如下图所示:
(3-1)
下面将详细介绍每一段:
3.1 正文段
当c程序执行时,会将可执行文件从磁盘拷贝到内存中,这个过程是由操作系统的加载器完成的。
正文段存储的是程序的机器指令,cpu就是根据这些指令去执行相应的操作的。正文段是由exec系统调用从可执行文件中读入的。
正文段的特征是只读共享的。
为了防止机器指令被改写,其被设置为只读。
为了减少内存的消耗,正文部分被设置为是只读的,即使多次执行同一个可执行文件,其机器指令都只有一个副本,大家共享一个。
3.2 初始化数据段
初始化数据段包含程序中需要明确赋值的变量。比如已赋值的全局变量、已赋值的静态变量。
3.3 未初始化数据段
未初始化数据段和初始化数据段的唯一区别就是其存储的变量是未赋初值的,内核将此区域的变量初始化为0或空指针。
3.4 栈
该段存储局部变量以及每次函数调用时所需保存的信息。最近调用的函数在栈上为其局部变量分配存储空间,所以递归函数中每次执行函数,其内的局部变量是互不影响的。
3.5 堆
有程序员动态申请的内存。
四、c程序结束后
c程序结束后,会进行如下操作:
返回状态码–》调用通过atexit注册的清理函数–》释放动态分配的内存–》关闭打开的文件–》结束进程并释放资源
最后又会回到c程序执行前的状态。
五、使用size来查看正文段、数据段、bss段
使用size命令可以查看可执行文件的正文段、数据段和bss段的大小,如下图所示:
(5-1)
其单位是字节,dec和hex是前三段的大小总和(十进制和十六进制表示)
参考资料:
《UNIX环境高级编程(第3版) (史蒂文斯 (W.Richard Stevens) 拉戈 (Stephen A.Rago))
(Z-Library)》