C语言内存布局

C语言从源程序文件(.c)到二进制程序文件(.exe或者.dll),需要经过三个阶段,编译->汇编->链接。编译阶段,将源程序文件编译成汇编代码。在由汇编程序,执行汇编代码,对应每个源程序文件生成一个目标文件(.obj)。最后通过链接将各个目标文件链接生成最后的可执行文件。在C语言中有六种数据段,可以分为两类:一类是静态生成的,类是动态生成的。不同的数据段,会在不同的阶段生成。下面首先介绍下这六种数据段的概念。
[b]代码段(Code)[/b]
由各个源程序的函数对应的机器代码组成,比如顺序代码(加、减、与等运算符),选择代码(if、if…else等选择运算符),循环代码(while等)。由源程序生成的目标文件中保存了函数对应的代码段。

[b]只读数据段(RO Data)[/b]
在程序中定义的不可改变的常量数据(const关键字修饰)。比如全局常量、局部常量、在程序中使用的常量。这部分数据段也保存在编译后生成的目标文件中。

[b]读写数据段(RW Data)[/b]
在程序中定义的可读可写的并且已经初始化的数据。例如已初始化的全局变量、局部静态变量。这部分数据保存在编译后生成的目标文件中。

[b]未初始化数据段(BSS)[/b]
和读写段类似,属于静态数据。和读写数据段的区别是它没有经过初始化。因为没有经过初始化,所在不占用目标文件的大小,只是在目标文件中标示该数据段的大小。只在程序初始化时产生。

[b]堆区[/b]
由malloc、calloc、realloc等分配内存的函数分配的堆内存。它在程序执行时,动态生成的内存。这部分内存很自由,由程序控制生成和释放。同时也很危险,很容易造成内存泄露,内存不足等错误。

[b]栈区[/b]
和堆区一样会在程序执行时动态生成。与堆不同的是,栈的生成和释放都是系统自动进行。所以相对来说很安全并且效率很高。栈中保存了函数的参数,函数中定义的变量(静态变量除外),以及函数返回值。每个函数对应一个栈帧,栈帧按照先进后出的顺序来释放空间。

在理解上面六种数据段后,我们在看各个数据段都在C语言哪些阶段产生。程序在通过编译汇编后,由C源程序文件生成对应的目标文件,目标文件中保存了每个函数的代码段,以及源程序文件中定义的只读数据段和读写数据段。未初始化数据段、堆和栈不会再这个阶段产生。在链接时,Link命令将所有的目标文件中的代码段、只读数据段和读写数据段进行抽出和重组。重新组合而成一个新的二进制文件。这个二进制文件就是可执行文件,它也是由程序段、只读数据段和读写数据段组合而成。未初始化数据段、堆和栈在这个阶段也还没有产生。当可执行文件进行初始化时,会产生未初始化数据段。在执行阶段产生堆和栈内存。这个就是C语言从编译到执行时内存的分配过程。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值