问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

C语言编程的内存布局

发布网友 发布时间:2023-09-24 04:26

我来回答

1个回答

热心网友 时间:2024-05-09 16:11

C语言编程程序的内存如何布局 C语言程序连接过程中的特性和常见错误 C语言程序的运行方式 一:C语言程序的存储区域 由C语言代码(文本文件)形成可执行程序(二进制文件),需要经过编译-汇编-连接三个阶段。编译过程把C语言文本文件生成汇编程序,汇编过程把汇编程序形成二进制机器代码,连接过程则将各个源文件生成的二进制机器代码文件组合成一个文件。 C语言编写的程序经过编译-连接后,将形成一个统一文件,它由几个部分组成。在程序运行时又会产生其他几个部分,各个部分代表了不同的存储区域: 1.代码段(Code或Text) 代码段由程序中执行的机器代码组成。在C语言中,程序语句进行编译后,形成机器代码。在执行程序的过程中,CPU的程序计数器指向代码段的每一条机器代码,并由处理器依次运行。 2.只读数据段(RO data) 只读数据段是程序使用的一些不会被更改的数据,使用这些数据的方式类似查表式的操作,由于这些变量不需要更改,因此只需要放置在只读存储器中即可。 3.已初始化读写数据段(RW data) 已初始化数据是在程序中声明,并且具有初值的变量,这些变量需要占用存储器的空间,在程序执行时它们需要位于可读写的内存区域内,并具有初值,以供程序运行时读写。 4.未初始化数据段(BSS) 未初始化数据是在程序中声明,但是没有初始化的变量,这些变量在程序运行之前不需要占用存储器的空间。 5.堆(heap) 堆内存只在程序运行时出现,一般由程序员分配和释放。在具有操作系统的情况下,如果程序没有释放,操作系统可能在程序(例如一个进程)结束后回收内存。 6.栈(stack) 栈内存只在程序运行时出现,在函数内部使用的变量、函数的参数以及返回值将使用栈空间,栈空间由编译器自动分配和释放。 C语言目标文件的内存布局 看一个例子: int a = 0; //全局初始化区,。data段 static int b=20; //全局初始化区,。data段 char *p1; //全局未初始化区 .bss段 const int A = 10; //.rodata段 void main(void) { int b; //栈 char s[] = "abc"; //栈 char *p2; //栈 static int c = 0; //全局(静态)初始化区 .data段 char *p3 = "123456"; //123456\0在常量区,p3 在栈上。 p1 = (char*) malloc(10);//分配得来的10和20个字节的区域就在堆区 p2 = (char*) malloc(20); strcpy(p1, "123456"); //123456\0 在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方 } 代码段、只读数据段、读写数据段、未初始化数据段属于静态区域,而堆和栈属于动态区域。代码段、只读数据段和读写数据段将在链接之后产生,未初始化数据段将在程序初始化的时候开辟,而堆和栈将在程序的运行中分配和释放。C语言程序分为映像和运行时两种状态。在编译-连接后形成的映像中,将只包含代码段(Text)、只读数据段(RO Data)和读写数据段(RW Data)。在程序运行之前,将动态生成未初始化数据段(BSS),在程序的运行时还将动态形成堆(Heap)区域和栈(Stack)区域。一般来说,在静态的映像文件中,各个部分称之为节(Section),而在运行时的各个部分称之为段(Segment)。如果不详细区分,可以统称为段。 知识点: C语言在编译和连接后,将生成代码段(Text)、只读数据段(RO Data)和读写数据段(RW Data)。在运行时,除了以上三个区域外,还包括未初始化数据段(BSS)区域和堆(Heap)区域和栈(Stack)区域。 二:C语言程序的段 1.代码段(code或text) 代码段由各个函数产生,函数的每一个语句将最终经过编绎和汇编生成二进制机器代码(具体生生哪种体系结构的机器代码由编译器决定)。 2.只读数据段(RO Data) 只读数据段由程序中所使用的数据产生,该部分数据的特点是在运行中不需要改变,因此编译器会将该数据段放入只读的部分中。C语言中的只读全局变量,只读局部变量,程序中使用的常量等会在编译时被放入到只读数据区。 注意:定义全局变量const char a[100]={"ABCDEFG"};将生成大小为100个字节的只读数据区,并使用“ABCDEFG”初始化。如果定义为:const char a[ ]={"ABCDEFG"};则根据字符串长度生成8个字节的只读数据段(还有’\0’),所以在只读数据段中,一般都需要做完全的初始化。 3.读写数据段(RW Data) 读写数据段表示了在目标文件中一部分可以读也可以写的数据区,在某些场合它们又被称为已初始化数据段,这部分数据段和代码段,与只读数据段一样都属于程序中的静态区域,但具有可写性的特点。通常已初始化的全局变量和局部静态变量被放在了读写数据段,如: 在函数中定义static char b[ 100]={“ABCDEFG”};读写数据区的特点是必须在程序经过初始化,如果只定义,没初始值,则不会生成读写数据区,而会定位为未初始化数据区(BSS)。如果全局变量(函数外部定义的变量)加入static修饰,这表示只能在文件内使用,而不能被其他文件使用。 4. 未初始化数据段(BSS) 与读写数据段类似,它也属于静态数据区,但是该段中的数据没有经过初始化。因此它只会在目标文件中被标识,而不会真正称为目标文件中的一段,该段将会在运行时产生。未初始化数据段只在运行的初始化阶段才会产生,因此它的大小不会影响目标文件的大小。 在C语言的程序中,对变量的使用还有以下几点需要注意: 1.函数体中定义的变量通常是在栈上,不需要在程序中进行管理,由编绎器处理。 2.用malloc,calloc,realloc等分配内存的函数所分配的内存空间在堆上,程序必须保证在使用free释放,否则会发生内存泄漏。 3.所有函数体外定义的是全局变量,加了static后的变量不管是在函数内部或外部都放在全局区。 4.使用const定义的变量将放于程序的只读数据区。 三:程序中段的使用 下面用一个简单的例子来说明C语言中变量和段的对应关系。C语言程序中的全局区(静态区),实际对应着下述几个段:RO Data; RW Data ; BSS Data. 一般来说,直接定义的全局变量在未初始化数据区,如果该变量有初始化则是在已初始化数据区(RW Data),加上const则将放在只读数据区。 const char ro[ ] = {"this is read only data"}; //只读数据区 static char rw_1[ ] ={"this is global read write data"}; //已初始化读写数据段 char BSS_1[ 100]; //未初始化数据段 const char *ptrconst ="constant data"; //字符串放在只读取数据段 int main() { short b; //在栈上,占用2个字节 char a[100]; //在栈上开辟100个字节, 它的值是其首地址 char s[ ]="abcdefg"; //s在栈上,占用4个字节,"abcdefg"本身放置在只读数据存储区,占8个字节 char *p1; //p1在栈上,占用4个字节 char *p2="123456"; //p2 在栈上,p2指向的内容不能改,“123456”在只读数据区 static char rw_2[ ]={"this is local read write data"};//局部已初始化读写数据段 static char BSS_2[100]; //局部未初始化数据段 static int c = 0; //全局(静态)初始化区 p1=(char *)malloc(10 * sizeof(char ) ); //分配内存区域在堆区 strcpy(p1,"xxxx"); //“XXXX”放在只读数据区,占5个字节 free(p1); //使用free释放p1所指向的内存 return 0; } 读写数据段包含了忆初始化的全局变量 static char rw_1[ ]以及局部静态变量static rw_2[ ].其差别在于编绎时,是在函数内部使用的还是可以在整个文件中使用。对于rw_1[] 无论有无static 修饰,其都将被放置在读写数据区,只是能否被其它文件引用与否。对于后者就不一样了,它是局部静态变量,放置在读写数据区,如果没static修饰,其意义完全改变,它将会是开辟在栈空间的局部变量,而不是静态变量,在这里rw_1[],rw_2[]后没具体数值,表示静态区大小同后面字符串长度决定。 对于未初始化数据区BSS_1[100]与BSS_2[100],其区别在于前者是全局变量,在所有文件中都可以使用;后者是局部变量,只在函数内部使用。未初始化数据段不设置后面的初始化数值,因此必须使用数值指定区域的大小,编绎器将根据大小设置BSS中需要增加的长度。 栈空间主要用于以下3数据的存储: 1.函数内部的动态变量 2.函数的参数 3.函数的返回值 栈空间是动态开辟与回收的。在函数调用过程中,如果函数调用的层次比较多,所需要的栈空间也逐渐加大,对于参数的传递和返回值,如果使用较大的结构体,在使用的栈空间也会比较大。
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
养胃的药最好的是什么啊 婴儿积食发烧不愿吃药怎么办 板门穴位在哪个部位 手机设置放偷看的方法? 凝结水回收器生产厂家? 个人账户养老金预测公式:现有5万元,缴费20年,能领多少钱? 临沂比较有名的男装品牌 呼伦贝尔市悦动网络科技有限公司怎么样? 呼伦贝尔中汇实业有限公司怎么样? 呼伦贝尔油玉不绝电子商务有限公司怎么样? 东方体育馆演唱会三脚架能进吗 苹果8plus接通没有声音怎么解决? The meeting [ ] for five hous last Saturday lasted中文翻译 ...英文中文都可以,最好有英文的),有助于写英语毕业论文的 ...毕业论文题目是【从电影喜福会浅析中美文化差异】,请哪位高手指点一... 跟有好感女孩说话时心跳加快呼吸困难怎么办 为什么我和她聊完天感觉心里空空的,在和她聊天的时候感觉心跳都加速了... 我跟女孩子说话 紧张 心跳加速 脸红 磕巴 害羞 这是怎么回事? 先声明... 和她聊天的时候为什么会心跳加速 乐清市嘉禾中学邮编 乐清嘉禾学校地址 描写一处环境安静的句子 形容安静的氛围的句子 火车东站到中国美院象山校区怎么走 杭州东站到浙江美术馆乘几号地铁 火车东站到浙江美术馆坐什么车 海南和风雅筑楼盘地址在哪里? 海南碧桂园东海岸在什么位置? 海南椰岛小城楼盘地址在哪里? 发广告违法吗? 前列回春胶囊 可以治前列腺吗 我老公管用前列腺炎,可以服用前列回春胶囊治疗吗? 男朋友喜欢叫别人名字最后一个字是什么意思 做黄金生意起个什么名字好 早上起来身体有3种现象的人,可能是血糖高了,做好4件事控制血糖_百度知 ... 当当网的满100元送50元礼券是在100元里除去还是什么 外地人怎么上天津新能源车牌 禾谷成熟的季节 请问如何注销广发银行的VISA奥运信用卡 用同音字组词:( )问( )兰 what best the cinemas in town同义句 BT下载软件BitComet里的“健康度”和“分享率”是什么意思? 请问bitcomet的分享率有什么用? 完美国际法师选哪个精灵?学哪个技能?加点呢? 谁知道macromedia dreameaver8的序列号,快快告诉我一下啊!谢谢!_百度... 天天炫斗商之渠85级配招 温州私立高中学校都有哪些啊? 郑州哪里租衣服 郑州市区哪里可以租到舞蹈用的衣服