符号表、程序运行时内存分区---《程序员自我修养》读书笔记

以下内容全部摘自《程序员的自我修养》,方便以后遇到类似的问题时能直接百度到,而不是需要去番薯,还不知道翻哪本书

  符号表:链接过程的本质就是要把多个同步不同的目标文件之间相互“粘”到一起,或者说是像玩具积木一样可以拼装形成一个整体。为了使不同目标文件之间能够相互粘合, 这些目标文件之间必须有固定的规则才行,就像积木模块 必须有凹凸部分才能够拼合。在链接过程中,目标文件之间的相互拼合实际上是目标文件之间对地址的引用,即对函数和变量的地址的引用。比如目标文件B要用到了目标文件A 中的函数“foo”,那么我们就成 目标文件A定义(define)了函数“foo”,称目标文件B引用了(Reference)目标文件A中的函数“foo”。这两个概念同样也适用于变量,每个函数都有自己独特的名字,才能避免链接过程中不同变量和函数之间的混淆。在链接过程中,我们将函数以及变量统称为符号,函数名或者变量名就是符号名符号表保存的就是部分符号,这些符号包括静态变量、全局变量和全局常量以及静态常量(除了函数中定义的栈变量,其他的都可以会加入到符号表中),(原文中好像是这么写的,至于栈常量是否属于符号表中的内容,我也给忘了,有兴趣的可以通读一下该书找找答案)。这下 终于知道了Visual studio编译时报错Link_ERROR 2019:找不到指定的符号的原因所在了

  程序的内存布局:在用户空间,也有许多地址区间有特殊的地位,一般来讲, 应用程序使用的内存空间里有如下"默认"的区域:

  栈:用于维护函数调用的上下文,离开了栈,函数调用就没法实现。栈通常在 用户空间的 最高地址处分配,通常 默认值有数兆大小

 堆:是用来容纳应用程序动态分配内存的区域,当程序使用 malloc或者new分配的内存时,得到的内存来自堆里。堆通常位于 栈的下方(低地址方向 )。堆一般 比栈大很多,可以有几十到数百兆字节的容量

  可行文件映像:在这里存储的是可执行文件在内存里面的映像,由装载器在 装载时将可执行文件的 内存读取或者映射到这里。

  保留区:保留区并不是一个单一的内存区域,而是对内存中收到保护而禁止 访问的内存区域的总称,例如:在大多数操作系统里,极小的地址通常都是不允许访问的,如NULL。通常C语言将无效指针赋值为0也是出于这个考虑,因为0地址上正常 情况下不可能有有效的可访问数据。某次在一个博客上我好像看到过保留区域的范围是(0------128M)

下面是一张linux中一个进程里面典型的内存布局,原图还是来自《程序员的自我修养》

上图还有个没有介绍的区域:“动态链接库映射区”,这个区域用于映射装载的 动态库连接,在linux中,如果可执行文件依赖于其他 共享库,那么系统会在从0x4000 0000开始的地址分配相应的空间,并将 共享库载入该空间中

最后给个建议:《程序员的自我修养》真的是本好书,出自潘爱民大神和另外两位大佬之手,潘大神还翻译了另外一本书《com本质论》,这本书上有我感兴趣的内容:C++的二进制不兼容问题的原因,《程序员的自我修养》这本读完了再去阅读后者

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值