一、C语言编译后可执行文件的存储区域划分图解及举例
1、C语言编译后可执行文件的存储区域划分图解:

2、举例说明各种变量存储区域分布:
int g_iInt0 = 0; //全局初始化为零,.bss段
static int g_iInt1 = 20; //全局初始化非零,.data段
char *g_pcChar0; //全局未初始化,.bss段
const int g_iInt2 = 10; //全局const只读变量,.rodata段
volatile const int g_iInt3 = 10; //全局volatile初始化非零变量,.data段
int main(int argc, char* argv[]) //代码区,.text段,argc和argv是函数入参,栈区
{
int iInt4; //局部变量,栈区
char *pcChar1; //局部变量,栈区
static int iInt5 = 0; //静态局部变量初始化为零,.bss段
static int iInt6 = 10; //静态局部变量初始化非零,.data段
static int iInt7; //静态局部变量未初始化变量,.bss段
const int iInt8 = 10; //局部常变量,栈区
char s[] = "123456"; //局部数组,栈区
char *pcChar2 = "123456"; //"123456\0"是字符串常量,.rodata段,pcChar2在栈区
g_pcChar0 = (char*)malloc(10); //分配得来的10和20个字节的区域,堆区
pcChar1 = (char*)malloc(20);
strcpy(g_pcChar0, "123456"); //"123456\0"是字符串常量,且与上面pcChar2指向"123456\0"的地址相同 .rodata段
printf("%s\n", "123456"); //"%s\n"及"123456\0"都是字符串常量,.rodata段
free(g_pcChar0); //注意手动申请内存使用结束后,需要手动释放已申请的内存,否则会出现内存泄漏
free(pcChar1);
return 0; //函数返回值,栈区
} 3、各种名词说明:
ELF文件:Executable and Linkable Format, ELF,可执行可链接格式;
.rodata:readOnly data,只读数据段;
段:Section(节)或者Segment(段);
总体来说,程序源代码被编译以后主要分成两种段:程序指令和程序数据。代码段数据程序指令,而数据段和.bss段属于程序数据。
.bss:Block Started by Symbol,BSS
二、存储区域详解
1、动态存储方式与静态动态存储方式:
从作用域(即从空间)角度来分,变量可以分为全局变量和局部变量。
从另一个角度,从变量值存在的作时间(即生存期)角度来分,变量可以分为静态存储方式和动态存储方式。
静态存储方式:是指在程序运行期间分配固定的存储空间的方式。
动态存储方式:是在程序运行期间根据需要进行动态的分配存储空间的方式。
用户存储空间可以分为三个部分:
程序区;
静态存储区;
动态存储区。
全局变量全部存放在静态存储区,在程序开始执行时给全局变量分配存储区,程序行完毕就释放。在程序执行过程中它们占据固定的存储单元,而不动态地进行分配和释放。
动态存储区存放以下数据:
函数形式参数;
自动变量(未加static声明的局部变量);
函数调用实的现场保护和返回地址。
对以上这些数据,在函数开始调用时分配动态存储空间,函数结束时释放这些空间。
2、冒牌货常量:C语言中的const说明:
其实const定义的是只读变量,而不是常量;
const 修饰的全局变量,已初始化的存储在.rodata段(是不是初始化的值放入到,而不是此变量?),(有的文献说初始化则存放在data区,未初始化放在bss区,待考证)
不可以直接修改;用指针的方式间接修改,编译不出错但是运行会出错
const修饰的局部变量, 存储在栈上
不可以直接修改;用指针的方式间接修改,编译不出错但是运行也不出错
用指针间接修改的方式可以改变const修饰的局部变量
误解一:用const修饰的变量值一定是不能改变的。实际:const修饰的局部变量可通过指针可间接修改。
三、说明及参考文献
1、说明:
1)、由于不同的操作系统及编译器编译后的结果是有差别的,所以上述图解及说明只是学习理解C语言编译后可执行文件(ELF文件)程序及数据分布的一种情况参考。
2)、希望该文章对大家有所帮助,请不要小看这简单的基础知识,但是由于参考文献差异及本人水平有限,文章难免有错误或不足之处,若有发现,请不吝赐教。
2、参考文献:
《计算机系统组成原理》
《程序员的自我修养》