6、c程序的内存布局

一般来说c程序具有如下的几个部分:

  • 文本段:这里包含 cpu 执行的机器指令。一般来说这个段是可以共享的,对于经常运行的程序来说,它在内存中只有一个拷贝,这个段也是只读的区域。
  • 初始化的数据段:一般简称为数据段,包含了在程序中指定初始化的数据。像类似 int a =99; 这样在所有函数之外被显示指定了初始值方式定义的变量就被初始化成为这类的数据段。
  • 未初始化的数据段:一般称作 bss 段。这样的数据段在程序运行之前被内核初始化成为0或者 null 指针。例如 int a[100]; 这样在所有函数之外定义的变量就被存储在这个数据段中。
  • 栈区:这个区域存放自动变量,用来保存函数调用的信息。
  • 堆区:运行时动态分配内存的时候会在这里申请,一般它在非初始化数据和栈区之间。
    一个典型的内存布局图示:


    图片.png

通过 size(1) 命令可以察看某个程序的文本段,数据段,以及 bss 段的大小。例如:

$size /usr/bin/cc /bin/sh
text     data   bss     dec     hex   filename
79606     1536   916   82058   1408a   /usr/bin/cc
619234    21120 18260  658614   a0cb6   /bin/sh

更为具体的信息,请参见后面给出的参考资料。

译者注

原文参考

参考: APUE2/ch07lev1sec6.html

7、共享库

大多数 unix 系统支持共享库,共享库把一些公共的函数从可执行文件中提取出来了,这样保证在运行的时候内存中只有一个库函数的拷贝。这样会减少可执行文件的大小,同时也带来了一些运行时间开销(在第一次启动可执行文件的时候以及第一次使用库函数的时候。)另外一个共享库优点就是如果库函数被修改了,那么只需要替换库文件就行了,不用重新链接程序(当然前提是那些被修改的函数的参数类型和数目是不变的)

程序可以要求使用或者不用共享库。例如可以通过 cc 或者 ld 的编译选项进行指定。

如: cc -static hello1.c

这样会导致程序在编译的时候不使用共享库。更为具体的信息在前面的预备知识“Linux系统中程序库文件简介”中描述了。

译者注

原文参考

参考: APUE2/ch07lev1sec7.html