【问题标题】:Where do uninitialized Global Variables go after initializing?初始化后未初始化的全局变量去哪了?
【发布时间】:2009-08-11 13:27:27
【问题描述】:

我在学习的时候遇到了一个小问题。我知道 C 中未初始化的全局变量被分配给可执行 ELF 文件中的 .bss 部分。但是当我开始使用它们时它们会发生什么? IE。他们是在堆上还是在其他地方占有一席之地?

我试图通过打印(仍未初始化的)全局变量的地址来找出

printf("%x",&glbl);

它总是返回相同的值 0x80495bc...为什么?

【问题讨论】:

  • 我注意到您在提出问题 5 分钟后接受了答案。如果您将其打开一段时间,您将获得更多答案,因为人们将更有动力改进答案。
  • 谢谢你的提示,我下次一定会这样做的。

标签: c linker elf


【解决方案1】:

当操作系统加载您的程序时,它会从您的程序地址空间分配足够的存储空间来存储 .bss 部分中的所有内容并将所有这些内存归零。当您分配、读取或获取变量的地址时,您正在操作分配的内存以提供 .bss 部分的存储空间。

【讨论】:

  • 啊,这也解释了为什么未初始化的全局变量包含的值总是为零。谢谢!
  • 一些编译器/架构支持小数据的 SBSS 部分。这通常作为一种优化来完成,以便可以通过从 SBSS 部分的开头进行索引来获取数据。这通常可以通过使用 gp 寄存器和 16 位索引来完成
【解决方案2】:

全局变量总是获得静态内存,如果它们未初始化,它们在二进制文件中没有空间,但是当二进制文件加载到进程内存空间时,它们确实会在内存中获得它。

【讨论】:

    【解决方案3】:

    BSS 是以可执行(或 ELF)格式定义的占位符。所以它不占用磁盘空间,而只是指定链接器或加载器应该分配哪些内存区域。

    具体操作取决于操作系统。由于您指的是 ELF,我认为它是用于嵌入式系统的。如果您为 ROMmable 代码构建,您的链接器 cmd 文件会将 BSS 映射到静态地址区域。

    如果您为操作系统(即 Linux)构建,来自操作系统的加载器将执行重定位传递,其中它将所有以可执行格式标记为相对的位置映射到内存中的物理或逻辑位置。

    因为您提到总是看到相同的值,这表明该过程对于您的系统是可重复的。当您更改链接器文件(即地址区域)、链接顺序(即模块将以不同的顺序分配空间)或操作系统时,预计会发生变化。

    无论您是否使用 BSS 值,地址对于您运行的进程都将保持不变。

    【讨论】:

      【解决方案4】:

      该 BSS 部分在进程地址空间中被赋予一个内存块,就像代码和堆栈部分(以及任何其他 ELF 可能有)一样。一旦到了那里,他们就不会任何地方。加载器安排事情然后调用进程入口点。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-13
        • 2017-09-12
        • 1970-01-01
        相关资源
        最近更新 更多