C语言--程序内存区域分配
参考:
https://www.cnblogs.com/bigbigtree/archive/2012/11/23/2784137.html
http://www.360doc.com/content/11/0330/21/1317564_105977930.shtml
http://hi.baidu.com/bitcore/blog/item/77c521c65f4512d7d10060eb.html
http://apps.hi.baidu.com/share/detail/22734757
http://my.oschina.net/alphajay/blog/3870
一、C语言可执行代码结构

一般情况下,一个可执行二进制程序(更确切的说,在Linux操作系统下为一个进程单元,在UC/OSII中被称为任务)在存储(没有调入到内存运行)时拥有3个部分,分别是代码段(text)、数据段(data)和BSS段。这3个部分一起组成了该可执行程序的文件。
(1)代码段(text segment):存放CPU执行的机器指令。通常代码段是可共享的,这使得被执行的程序只需要在内存中拥有一份拷贝即可。代码段也通常是只读的,防止其他程序意外地修改其指令。另外,代码段还规划了局部数据所申请的内存空间信息。
代码段(code segment/text segment)通常是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于只读, 某些架构也允许代码段为可写,即允许修改程序。在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等。
(2)数据段(data segment):数据段分为只读数据段、可读可写数据段和BSS数据段。只读数据段存放除字符串常量外的其他常量,以及由const修饰的全局变量。初始化的全局变量、静态变量(全局和局部)存放在可读可写数据段,而未初始化的全局变量、静态变量(全局和局部)存放于BSS数据段。
值得注意的是,const修饰的局部变量是存放于栈中的,在c语言中可以通过指针对const局部变量进行修改。c中const默认为外部连接,c++中const默认为内部连接。当c语言两个文件中都有const int a的时候,编译器会报重定义的错误。
而当程序被加载到内存单元时,则需要另外两个域:堆域和栈域。C语言程序在存储时分为3个段:BSS数据段、普通数据段、代码段。运行时分为5个区域:堆、栈、数据区(BSS数据段、只读数据段、可读可写数据段)、代码区。
(4)栈段(stack):存放函数的参数值、局部变量的值,以及在进行任务切换时存放当前任务的上下文内容。
(5)堆段(heap):用于动态内存分配,即使用malloc/free系列函数来管理的内存空间。
在将应用程序加载到内存空间执行时,操作系统负责代码段、数据段和BSS段的加载,并将在内存中为这些段分配空间。栈段亦由操作系统分配和管理,而不需要程序员显示地管理;堆段由程序员自己管理,即显示地申请和释放空间。
另外,可执行程序在运行时具有相应的程序属性。在有操作系统支持时,这些属性页由操作系统管理和维护。
程序例子
1 include <stdio.h> 2 const int g_A = 10; //代码段 3 int g_B = 20; //数据段 4 static int g_C = 30; //数据段 5 static int g_D; //BSS段 6 int g_E; //BSS段 7 char *p1; //BSS段 8 9 void main( ) 10 { 11 int local_A; //栈 12 static int local_C = 0; //数据段 13 static int local_D; //数据段 14 15 char *p3 = "123456"; //123456在代码段,p3在栈上 16 17 p1 = (char *)malloc( 10 ); //堆,分配得来得10字节的区域在堆区 18 strcpy( p1, "123456" ); //123456字符串寸放在常量区, 19 //编译器可能会将它与p3所指向的 20 //"123456"优化成一块 21 }

浙公网安备 33010602011771号