变量前缀和存储位置的关系.docxVIP

  1. 1、本文档共4页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  5. 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  6. 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  7. 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  8. 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
变量前缀和存储位置的关系

进程中内存空间的划分:1.???????代码区?–?存放代码/函数,只读区2.???????全局区?–?保存全局变量,读写区3.???????BSS段?–?未初始化的全局变量,BSS段在main执行前会自动清04.???????栈区?–?存局部变量,包括函数形参,栈区的内存是自动分配自动回收的5.???????堆区?–?程序员自己管理的区域,malloc/ free操作的都是堆区。6.???????只读常量区?–?存放字符串常量和const修饰的全局变量。注:只读常量区和代码区合并在一起。?上面的这种划分在很多文档中都有看到,这里我不想再一一介绍。只想说一下其中的误解和陷阱,本文讲以一下几部分展开:1)变量前缀和储存位置2)为什么要有bss段,全局变量未初始化到底放哪?3)linux察看内存分配的map文件?一,变量前缀 和 储存位置:???????这部分帮助大家回顾const, static,auto,全局,局部等变量常量的储存位置。首先看下面的一个小程序:constint i2 = 10;int * p2 = i2;*p2 = 200;printf(%d\n,i2);大家猜猜输出的结果。是不是会出现编译错误或者运行时错误????????答案是:输出200。运行时有警告:非常指针指向常变量。再看下面的一段代码:? 1 #include stdio.h?????????????????????????????????????????????????????????? 2 intmain()? 3 {? 4???? char *a=asdaasasda;? 5???? char *p = a;? 6???? *p = z;? 7????printf(%s\n, a);? 8????return 0;?9 }运行时会提示:段保护错误。这说明局部的const常量并不是保存在常量区,而是和一般的可变常量一样,保存在栈区。只是通过编译阶段错误机制防止变量内容被改变,运行时无法保证,并且函数退出被释放。再来看static,参考文章开头给的分区机制:static变量肯定不能在栈区,因为生存周期是整个文件,所以肯定在全局变量区。而全局变量区和只读常量区就成了所有生存周期贯穿文件的变量的存放位置。那么,第二段代码中的字符串存在只读常量区,也就是说整个生存周期贯穿文件,也就是说,在函数外也可以通过指针进行访问。这是我们的猜测,那么真实的情况呢?? 1 #include stdio.h?????????????????????????????????????????????????????????? 2 char *f()?3 {? 4???? char *t = happy!;? 5???? return t;?6 }? 7 intmain()? 8 {? 9???? char *a=asdaasasda;?10???? //char *p = a;?11???? //*p = z;?12???? //printf(%s\n, a);?13????printf(%s\n,f());?14???? return 0;?15 }执行结果:happy!?这样我们可以得出结论:多种声明方式容易搞混,而其实只有生存周期和存储位置的对应关系是不变的。长周期变量:必然存在全局区和常量区,而临时变量都存在栈区。反之亦然:存在全局区的和常量区的都是长周期变量,栈区都是临时变量。隐式声明:char *str = XXXX;其实是static const的。或者可以理解在编译阶段字符串被抽取出来随文件一起保存。?二,可爱的BSS段:BSS段的全称是什么?很多人知道bss段是存储未初始化全局变量的,可是没有去想为什么系统要单独开辟一个区去存未初始化全局变量?bss区有什么特殊的地方,使得他适合去存储未初始化的全局变量?下面为大家解决这些问题:BSS(Block Started by Symbol),如果大家对汇编有所了解,肯定知道block的概念。我们在C代码中定义的变量都是按照block存的。数组名就是block首地址的symbol。一般都是这样的格式:AAA??????dw 0,1,2.....AAA后面没有冒号,在运行时如果用AAA做相对寻址,其单元大小都是dw。这就是汇编里对应数组的结构:block。BSS段中有很多数组?对还是错?其实by symbol就是告诉我们有很多数组symbol,但是后面的具体数据并不在bss中。那么这就像一张列出数组symbols的表格了。那么为什么要搞这么一张表,不能直接存数据么?你可以想象如果数组很大,怎么把这么多数据写在二进制文件中。那将会使得文件很大。最关键的是,一会我们会看到,开始分配4G内存的时候,全局变量区的大小是定死了

文档评论(0)

hhuiws1482 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

版权声明书
用户编号:5024214302000003

1亿VIP精品文档

相关文档