用户登录
用户注册

分享至

一起talk C栗子吧(第一百三十一回:C语言实例--C程序内存布局三)

  • 作者: 嗳祢莪等祢
  • 来源: 51数据库
  • 2021-11-21

各位看官们,大家好,上一回中咱们说的是c程序内存布局的例子,这一回咱们继续说该例子。闲话休提,言归正转。让我们一起talk c栗子吧!

看官们,关于c程序内存布局的例子,我们在前面的两个章回都介绍过了,这一回我们将对前面章回中的内容进行总结和提示。

内存布局总结

c程序的内存布局主要有四个分区:代码区,数据区(data和bss),堆区和栈区。可以使用readelf -s filename查看各个分区的内存地址。这四个分区在内存中从低地址空间开始依次向高地址延伸。我们再次使用前面章回中的图直观地展示给大家,并且对这些分区做一个全面的总结。

代码区:主要存放程序的代码,位于内存的低地址空间中。 数据区:<001a喎? f/ware/vc/"="" target="_blank" class="keylink">vc3ryb25npsv8tcs12na3v9w85m6709q0+slrx/jjz8pmo6zw99kqtoa3xbpm0plw0lxesetbv6ossru5/bqvyv3w0lxevtayv7fhvrlmrlhkwb+yu9taumph+npy1tcjrlb4ysfu2tw7x/jw0kgjudjt2rhkwb+1xmdg0m2yu82so6y05rfftcth+npy0rkyu82so6y4/lztz+rpulxeu6631qosx+uyzr+8z8ld5mrhdgg6zwjzc8/gudi1xndfz6khoya8c3ryb25npmrhdge8l3n0cm9uzz461vfsqrtmt8wzzndy1tcz9cq8u6+1xmirvtax5mg/us2+1rk/vrlmrlhkwb+ho8bk1tdiq77wsetbv7k708ph+lfwvrlmrlrnt8e+ssyso6zwu9kqysfiq77wsetbv7a81nq4w8f40/lw0kgjidxzdhjvbmc+ynnzojwvc3ryb25nptb30qq05rffs8zq8tbqzrsz9cq8u6+1xmirvtax5mg/us2+1rk/vrlmrlhkwb+ho8bk1tdiq77wsetbv7k708ph+lfwvrlmrlrnt8e+ssyso6zwu9kqysfiq77wsetbv7a81nq4w8f40/lw0kgjidxzdhjvbmc+tthh+ko6pc9zdhjvbmc+zrvt2sr9vt3h+mnpw+ajrlbrx/i1xltz0kgyu7nmtqijrmv81vfsqrtmt8wzzndy1tc2r8yst9bf5lxexnq05qgjumph+npytcs31sxkus272mrv08mzzndy1lhx1ly6v9jwxqos0vk0y9kyyn3s17p2zsrm4qgjidxzdhjvbmc+1bvh+ko6pc9zdhjvbmc+zrvt2rbrx/jjz8pmo6zvu8f4tcs089ch0rkyu7nmtqijrmv81vfsqrtmt8w6r8r91tc1xl7wsr+3x76yzkyx5mg/us26r8r9tfftw8/gudi1xndfz6kho7jdx/jt8tpjz7xns7340nc53mdto6yzzndy1lgyu8tcv9jwxqgjdqo8cd7x3l3hzeq31sf4tcte2sjduvojrm7sw8e94brpx7dd5txcu9jw0lxewp3x06os19y94dk7z8la/dft1tc497j2setbv9taxnq05tbqtcs31rk80mxpoqostpo80rtt1tc/ydluv7s1vaoswp3x09bqupe49rhkwb/u2statobw0lxet9ayvlrnztldx8npw+bx3l3htcte2sjdzeriq9k71skhozwvcd4ncjxwcmugy2xhc3m9"brush:java;"> 内存分区 分区起始地址 分区中存放的变量和代码 栈区: 0xbfde3000 存放函数和局部变量:la1,la2,i 堆区: 0x0964d000 存放动态分配的内存空间:p所指向的空间. 数据区中的bss区: 0x0804a038 存放程序中未初始化的全局变量和局部静态变量:ga1,static_la1 数据区中data区: 0x0804a028 存放程序中初始化的全局变量和局部静态变量:ga2,static_la2 代码区: 0x080483e0 存放程序的代码

内存布局细节

除了总结外,我们还有一些小的细节需要共享给大家。希望引起大家的注意:

1.在内存布局图中堆区和栈区的分界处各有一条绿线。它表示堆区和栈区的大小是在变化的,它们不像代码区和数据区一样拥有固定的大小。 2.堆区的内存空间是从低地址向高地址延伸,而栈区的内存空间是从高地址向低地址延伸。尽管它们都是大小可以变化的分区,但是在分区变化的方向上正好相反。 3.程序中代码区和数据区的地址空间是固定的,不会随着程序运行而发生变化。但是程序中堆区和栈区的地址空间是动态变化的。已经有细心的看官发现了,我们在上一回中的例子,运行过两次,位于数据区中的变量地址在两次运行结果中完全一致,但是位于堆区和栈区中的变量地址在两次运行结果中不相同。这便是最好的证明。

内存布局之外

看官们,俗话说的好,当局者迷,旁观者清。在大家仔细观察内存中的各个分区时,让我们跳出这些分区之外,从整个内存的角度来做一些说明,希望能把大家就“迷局”中拉出来 。

1.我们在这些章回中说的地址都是指虚拟内存地址,这点在一百二十九回介绍过。 2.内存的布局除了我们介绍的这四个分区外,还有其它的分区。只是这四个分区与代码的关系更切一些。 3.使用readelf工具可以查看可执行文件中的分区信息,不过这里只使用了该命令的s选项,其它的选项没有介绍,大家可以自己摸索一下。 4.通过/proc虚拟目录中的文件来查看内存相关的信息,主要有cmdline,maps,status。readelf查看的是程序已经固定的静态信息,像堆,栈这些动态信息,就需要查看proc目录中的文件了,该目录中的文件提供了程序运行时的实时信息。

各位看官,关于c程序内存布局的例子咱们就说到这里。欲知后面还有什么例子,且听下回分解 。


软件
前端设计
程序设计
Java相关