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 }        

 

posted @ 2019-08-29 13:16  ztnb1997  阅读(465)  评论(0)    收藏  举报