2010-08-20 125 views
3

如我们所知.bss包含未初始化的变量。如果在c代码中,程序员在使用它们之前初始化变量。那么.bss在执行C代码之前不必为零。.bss部分不是零初始化

我对不对?

由于

回答

11

在C代码,具有静态存储持续时间的任何变量被定义为通过该规范(第6.7.8初始化,第10段)被初始化为0:

如果一个对象,该具有静态存储持续时间未明确初始化,则:

  • 如果它有指针类型,则它被初始化为空指针;
  • 如果它有算术类型,它被初始化为(正或无符号)零;
  • 如果它是一个聚合,每个成员根据这些规则初始化(递归);
  • 如果它是一个联合,则根据这些规则初始化(递归)第一个命名成员。

一些程序加载器将填补用零整节开始,和其他人将填补其“按需”为演出内容的改进。所以,当你在技术上是正确的,因为.bss部分可能不真的包含全零的C代码开始执行时,逻辑一样。无论如何,假设您有一个符合标准的工具链,您可以将其视为全零。

被初始化为非零值在.bss部分永远不会结束了任何变量;它们在.data.rodata部分处理,具体取决于它们的特性。

1

这取决于变量在代码中的位置。例如,如果你正在讨论main()或其他函数中的局部变量,那么变量会被压入堆栈(除非使用其他修改关键字)。如果你的变量是全局和未初始化的,那么它应该保存在.bss中。请注意,编译器优化等可能会改变一些事情。如果你确实想知道使用readelf来调查linux上的ELF二进制文件。

+0

静态存储持续时间明确初始化为0的任何变量也可能以.bss节结束。 – 2010-08-20 15:31:58

4

ELF规范说:

的.bss此节包含未初始化的数据 有助于程序的 内存映像。根据定义,当程序开始运行时, 系统使用零初始化数据 。所述 部分占据没有文件的空间,如由 区段类型, SHT_NOBITS指示。

它因此得出结论,其具有分配给它的值C全局变量不能被放入.bss段,将不得不进入.data段。 .data部分包含分配给它的所有变量的初始值。

-1

看起来好像你可能会对.bss部分结束零初始化的机制感到困惑。您编译的代码无法将区域显式初始化为零,因为操作系统首先为进程分配新页面的内存时,操作系统会确保页面初始化为零。这是出于安全原因而完成的,以便进程无法查找其他进程退出时留在内存中的秘密。

+0

您假定代码正在由操作系统运行,而不是这种情况,这就是为什么当某些变量需要未初始化时,它需要在.bss中。是因为.bss IS实际上是零填充的 – 2013-03-01 00:25:15