参考:《UNIX环境高级编程》第7章 7.6节
C程序一般有下面几部分构成
正文段:又叫文本段,这是有CPU执行的机器指令部分。通常,正文段是可以共享的,并 且是只读的。
初始化数据段:通常将此段作为数据段,它包含了程序中需要明确的赋初值的变量,比如函 数外的声明:int cnt = 10;
非初始化数据段:通常此数据段称为bss段(block start symbol),在程序开始执行之前,内核 将此段中的数据初始化为0或空指针。比如函数外声明:int arr[100];
栈:自动变量以及每次函数调用所需保存的信息都存放在此段中。调用函数其返回地址也保 存在栈中。递归函数每调用一次自身,就是用一个新的栈帧,这样一个函数调
用中的变量集就不会影响另一个函数调用函数的变量。
堆:通常在堆中进行动态存储分配,由于历史上的惯例,堆位于非初始化数据段和栈之间。
size命令报告正文段、数据段和bss段长度(单位:字节)
测试实例:
#include "apue.h" void myexit(void) { printf("I am in myexit.\n"); } int main(void) { printf("I am in main.c\n"); return 0; }
把程序改为
#include "apue.h" void myexit(void) { printf("I am in myexit.\n"); } int main(void) { printf("I am in main.c\n"); return 0; }
结论:1、未初始化的全局变量保存在bss段
当把程序改为
#include "apue.h" void myexit(void) { printf("I am in myexit.\n"); } int a = 1; int main(void) { printf("I am in main.c\n"); return 0; }
结论:2、初始化的全局变量保存在数据段中
当把程序改为
#include "apue.h" void myexit(void) { printf("I am in myexit.\n"); } static int a; int main(void) { printf("I am in main.c\n"); return 0; }
结论:3、未初始化的静态变量保存在bss段中
当把程序改为
#include "apue.h" void myexit(void) { printf("I am in myexit.\n"); } static int a = 1; int main(void) { printf("I am in main.c\n"); return 0; }
结论:4、初始化的静态变量保存在数据段中
当把程序改为
#include "apue.h" void myexit(void) { int a; printf("I am in myexit.\n"); } int main(void) { printf("I am in main.c\n"); return 0; }
结论:5、函数内部声明的局部变量保存在堆栈段中
未初始化数据段的内容并不存放在磁盘上的程序文件中,因为内核在程序开始运行前将它们都设置为0,。需要存放在程序文件中的段只有正文段和初始化数据段。
Linux中的size命令输出不包括stack和heap的部分,只包括文本段(test)、代码段(data)和未初始化数据段(bss)三部分。
小结:
1、未初始化的全局变量保存在bss段
2、初始化的全局变量保存在数据段中
3、未初始化的静态变量保存在bss段中
4、初始化的静态变量保存在数据段中
5、函数内部声明的局部变量保存在堆栈段中
6、未初始化的静态变量(包括全局和布局变量)保存在bss段
7、初始化的静态变量(包括全局和局部变量)保存在data段
原文地址:http://blog.csdn.net/u012796139/article/details/41727851