Chinaunix首页 | 论坛 | 博客
  • 博客访问: 228172
  • 博文数量: 93
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 542
  • 用 户 组: 普通用户
  • 注册时间: 2014-12-09 16:59
文章分类

全部博文(93)

文章存档

2016年(27)

2015年(66)

我的朋友

分类: C/C++

2015-08-27 20:46:38

    一个可执行程序可分为代码和数据两部分,代码在内存中存储在代码段,对于代码中包含的一些常量可能放在代码段中,也可能放在专门的常量区。数据则有全局,局部,动态和静态之分,对于全局数据(无论动态和静态)和静态局部数据,它们的内存分配属于静态分配,在程序开始执行时静态分配内存;对于非静态局部数据,它们的内存分配属于动态分配,在其所在的函数被调用时动态地分配内存,具体可分为以下几种情况:

1. 对于已指定初始值的全局变量和静态局部变量,在程序开始时分配存储空间到数据段(.data段)并初始化;

2. 对于未指定初始值的全局变量和静态局部变量,在程序开始时分配存储空间到BSS段(.bss段),未指定值初始化但BSS段会自动清零,所以未指定初始值的全局变量和静态局部变量看起来使用默认的零值初始化了

3. 对于动态局部变量(程序中临时创建的变量)在程序开始时并未分配存储空间,在调用其所在函数时才动态的分配存储空间到栈

4. 由上可见,数据段,BSS段,堆,栈还有代码段都是一块内存区域,是硬件,在程序由硬盘读到内存时被使用,其中数据段,BSS段和代码段在程序开始时静态分配内存,属于静态存储区,堆和栈在动态临时局部变量创建时(即函数被调用时)动态分配内存,属于动态存储区

静态局部变量(无论指未指定初始值)在函数调用时已有初始值,不再在函数调用时执行初始化语句,当然对它的赋值语句依然执行。

对于非静态局部变量,当其所在函数被调用时,这时栈会给函数中所有定义的非静态局部变量分配空间,无论此变量有没有初始值,栈给函数分配的空间可能大于函数所需的空间,会造成一定的空间浪费,当函数结束时释放这些空间。

对于函数中的char *p = "abcd";其中p存储在栈中,字符串常量存储在常量区,并不在栈中占存储空间;

又如:char str[8] = "asdfg";其中字符串常量也是存储在常量区,并不在栈中占存储空间,但与p不同的是str[8]存储在栈中,占8个字节;

对于int i = 0;其中的常数0则和代码一起存储在代码段。




以下为网络转载的可执行程序分段的基本概念:

一个可执行程序包括BSS段、数据段、代码段(文本段)。

bss segment ,data segment ,code/text segment

①BSS(Block by Start Symbol) :通常指用来存放程序中未初化的全局变量和静态变量的一块内存区域。BSS段属于静态内存分配。

特点是:可读写的,在程序执行之前BSS段为自动清零,所以未初始的全局变量在程序执行之前已经成零了。

②数据段:通常用来存放程序中已初始化的全局变量和静态变量的一块内存区域。

DATA segment 属于静态内存分配。

③代码段:通常是指用来存放程序代码的一块内存区域,这部分区域的大小在程序运行前就已确定,并且内存区域通常属于只读,某些架构允许代码段可写,即可以修改,在代码段中,也有可能包含一些只读的常数变量,例如字符串变量等。

④堆(heap):用于存放程序中被动态分配的内存段,大小不固定,可动态扩大或缩减,malloc /free 

⑤栈(stack):用来存放程序临时创建的局部变量,但不包括static声明的变量。除此之外,在函数被调用时,其参数也会被压入发起调用的堆栈中,并且待到调用结束后,函数的返回值也会被放会栈中,由于栈的先进后出的特点,所以栈特别方便用来保存/恢复调用现场,从这个意义来讲,我们可以把堆栈看成一个寄存、交换临时数据的内存区。

 

DEMO:

program 1:

int ar[30000];  

int main(void)  

{  

    ....  

}  


program 2:

int ar[30000]={1,2,3,4,5,6};  

int main(void)  

{  

    ....  

}  


在VS中跑了一下这两段代码,发现program 1编译出来的.exe的大小为28KB,program 2编译出来的.exe的大小为172KB.

区别在于一个位于BSS段,另一个位于DATA段。两者的区别在于:全局的未初始化变量存在于.bss段,具体体现为一个点位符;全局的已初始化变量存于.data段,而函数内的自动变量在栈上分配存储空间。.bss段是不占用.exe文件空间的,其内容由操作系统初始化为0,而.data段却需要占用,其内容由程序进行初始化,所以造成了上述情况。

bss段(未手动初始化的数据)并不给该段的数据分配空间,只是记录数据所需空间的大小。

data段(已手动初始化的数据)段则为数据分配空间,数据保存在目标文件中。

数据段包含经过初始化全局变量以及它们的值。BSS段的大小从可执行文件中得到,然后链接器得到这个大小的内存块,紧跟在数据段的后面。当这个内存区进入程序的地址空间后全部清零。包含数据段和BSS段的整个区段通常称为数据区。

转载






阅读(1229) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~