C语言内存区域分配

阅读Unix环境高级编程的时候,读到了程序存储空间分配,借鉴了网上的一些资料总结如下:

 

一、C语言可执行代码结构
 

名称存储内容
代码段可执行代码、字符串常量 、只读的常数变量
数据段已初始化全局变量、已初始化全局静态变量、局部静态变量、常量数据
BSS段未初始化全局变量,未初始化全局静态变量  
局部变量、函数参数  
动态内存分配


 一般情况下,一个可执行二进制程序(更确切的说,在Linux操作系统下为一个进程单元,在UC/OSII中被称为任务)在存储(没有调入到内存运行)时拥有3个部分,分别是代码段(text)、数据段(data)和BSS段。这3个部分一起组成了该可执行程序的文件。
(1)代码段(text segment):

Unix环境高级编程称为正文段,存放CPU执行的机器指令。通常代码段是可共享的,这使得需要频繁被执行的程序只需要在内存中拥有一份拷贝即可。代码段也通常是只读的,这样可以防止其他程序意外地修改其指令。另外,代码段还规划了局部数据所申请的内存空间信息。 代码段(code segment/text segment)通常是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于只读, 某些架构也允许代码段为可写,即允许修改程序。在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等。


(2)数据段(data segment):

或称全局初始化数据段/静态数据段(initialized data segment/data segment)。该段包含了在程序中明确被初始化的全局变量、静态变量(包括全局静态变量和局部静态变量)和常量数据。


(3)未初始化数据段:

亦称BSS(Block Started by Symbol)。该段存入的是全局未初始化变量、静态未初始化变量。而当程序被加载到内存单元时,则需要另外两个域:堆域和栈域。图1-1所示为可执行代码存储态和运行态的结构对照图。一个正在运行的C程序占用的内存区域分为代码段、初始化数据段、未初始化数据段(BSS)、堆、栈5个部分。

 

(4)栈段(stack):

存放函数的参数值、局部变量的值,以及在进行任务切换时存放当前任务的上下文内容。


(5)堆段(heap):

用于动态内存分配,即使用malloc/free系列函数来管理的内存空间。
在将应用程序加载到内存空间执行时,操作系统负责代码段、数据段和BSS段的加载,并将在内存中为这些段分配空间。栈段亦由操作系统分配和管理,而不需要程序员显示地管理;堆段由程序员自己管理,即显示地申请和释放空间。

 

测试代码如下:

[cpp]  view plain copy
  1. #include <stdio.h>  
  2. #include <string.h>  
  3. #include <stdlib.h>  
  4.   
  5. const int    global_one = 10;    //代码段  
  6. int          global_two = 20;    //数据段  
  7. static int   global_three = 30;  //数据段  
  8. static int   global_four;        //BSS段  
  9. int          global_five;        //BSS段  
  10. char         *pa;                //BSS段  
  11.   
  12. int main( )  
  13. {  
  14.     int         local_one;       //栈  
  15.     static int  local_two = 0;   //数据段  
  16.     static int  local_three;     //数据段  
  17.      
  18.     char        *pb = "1234567"//1234567在代码段,pb在栈上  
  19.     pa = (char *)malloc( 10 );   //堆  
  20.     strcpy( pa, "1234567" );     //1234567放在常量区  
  21.       
  22.     printf("==========txt segment=============\n");  
  23.     printf( "global_one   ,addr:%p\n", &global_one);  
  24.       
  25.     printf("\n==========data segment==========\n");  
  26.     printf( "global_two   ,addr:%p\n", &global_two);  
  27.     printf( "global_three ,addr:%p\n", &global_three);  
  28.     printf( "local_two    ,addr:%p\n", &local_two);  
  29.     printf( "local_three  ,addr:%p\n", &local_three);  
  30.       
  31.     printf("\n=============BBS===============\n");  
  32.     printf( "global_four  ,addr:%p\n", &global_four);  
  33.     printf( "global_five  ,addr:%p\n", &global_five);  
  34.     printf( "pa           ,addr:%p\n", pa);  
  35.   
  36.     printf("\n=============stack=============\n");  
  37.     printf( "local_one    ,addr:%p\n", &local_one);  
  38.     printf( "pb           ,addr:%p\n", pb);  
  39.       
  40.     printf("\n=============heap=============\n");  
  41.     printf( "pa           ,addr:%p\n", pa);  
  42.       
  43.     return 0;  
  44. }  
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值