Linux环境编程之进程(二):程序的存储空间布局
引言:
一个写好的程序一般要存放在存储器中,那么程序中的代码、数据等各部分,是如何有规律的存放在存储器中的呢?
(一)
一个存储的程序可分为五部分:正文段、初始化数据段、非初始化数据段、栈、堆。其典型的存储安排如下图:
正文段:这是由CPU执行的机器指令的部分。通常,正文段是可共享的,所以即使是频繁执行的程序在存储器中也只需要一个副本,另外正文段常常是只读的,以防止程序由于意外而修改其自身的指令。
初始化数据段:通常称为数据段,它包含了程序中需要明确地赋初值的变量。
非初始化数据段:通常称为bss段。在程序开始执行之前,内核将此段中的数据初始化为0或空指针。
栈:自动变量以及每次函数调用时所需保存的信息都存放在此段中。每次调用函数是,其返回地址以及调用者的环境信息都存放在栈中。然后,最近被调用的函数在栈上为其自动和临时变量分配存储空间。
堆:通常在堆中进行动态存储分配。
Linux中使用size命令可以查看文件的正文段、数据段和bss段的长度。
(二)
存储器分配:一般用于存储空间动态分配的函数有malloc/calloc/realloc。
1、malloc:分配指定字节数的存储区。此存储区中的初始化值不确定。
2、calloc:为指定数量的对象分配存储空间。该空间中的每一位都初始化为0。
3、realloc:更改以前分配区的长度(增加或减少)。
动态内存管理的优势:能够动态的满足对内存空间的需求。
(三)
共享库:共享库使得可执行文件中不再需要包含公用的库例程,而只需要在所有进程都可引用的存储区中维护这种库例程的一个副本。程序第一次执行或第一次调用某个库函数时,用动态链接方法将程序与共享库函数相链接。这减少了每个可执行文件的长度,但增加了一些运行时间开销。共享库的另一个优点是可以用库函数的新版本代替老版本,而不需要对使用该库的程序重新连接编辑。