【问题标题】:Is global memory initialized in C++?全局内存是否在 C++ 中初始化?
【发布时间】:2010-09-08 19:22:18
【问题描述】:

全局内存是否在 C++ 中初始化?如果有,怎么做?

(第二次)澄清:

当程序启动时,在初始化原语之前,内存空间中有什么将成为全局内存?我试图了解它是归零还是垃圾。

情况是:可以在初始化之前通过instance() 调用设置单例引用吗:

MySingleton* MySingleton::_instance = NULL;

然后得到两个单例实例?

查看我关于单例的多个实例的 C++ 测验...

【问题讨论】:

    标签: c++ memory memory-management


    【解决方案1】:

    来自标准:

    在任何其他初始化发生之前,具有静态存储持续时间 (3.7.1) 的对象应进行零初始化 (8.5)。零初始化和用常量表达式初始化统称为静态初始化;所有其他初始化都是动态初始化。使用常量表达式 (5.19) 初始化的具有静态存储持续时间的 POD [plain old data] 类型 (3.9) 的对象应在任何动态初始化发生之前进行初始化。在同一翻译单元的命名空间范围内定义的静态存储持续时间并动态初始化的对象应按照其定义在翻译单元中出现的顺序进行初始化。 [注:8.5.1 描述了聚合成员的初始化顺序。最初的- 局部静态对象的化在 6.7 中描述。]

    所以是的,具有静态存储持续时间的全局变量将被初始化。在堆上分配的全局变量当然不会自动初始化。

    【讨论】:

      【解决方案2】:

      是的,全局原语被初始化为 NULL。

      例子:

      int x;
      
      int main(int argc, char**argv)
      {
        assert(x == 0);
        int y;
        //assert(y == 0); <-- wrong can't assume this.
      }
      

      你不能对堆上的类、结构、数组、内存块做任何假设......

      始终初始化所有内容是最安全的。

      【讨论】:

      • 我相信您可以对 C++ 中的 y==0 做出这样的假设。一切都有一个默认初始化器,对于数字类型,它是 0。
      • Branan,你不能依赖它。该标准不要求对非静态变量进行零初始化。大多数编译器初始化非静态变量,因为它会产生运行时成本。
      • 内置类型的默认 ctor 会将它们归零,但是默认 ctor 不会被隐式调用。有关内置类型的默认初始化示例,请参见例如std::pair&lt;int, bool&gt;
      • Edit 这个答案是错误的——你不能对编译器对非静态存储的默认初始化做出任何假设,除非你有一个编译器标志来保证初始化为零。
      • 内置类型没有构造函数;他们是 POD。诸如“int i = int();”之类的东西或成员初始化器列表中的 int_member(),看起来像构造函数调用,实际上称为“值初始化”。
      【解决方案3】:

      来自嵌入式世界...

      您的代码被编译成三种类型的内存:
      1. .data:初始化内存
      2. .text:常量和代码
      3. .bss:未初始化的内存(如果没有显式初始化,在C++中初始化为0)

      如果初始化,全局变量会进入 .data。如果不是,则将它们放在 .bss 中并在主代码中归零。

      【讨论】:

        【解决方案4】:

        用静态/全局范围声明的变量总是至少在 VC++ 下初始化。

        在某些情况下,以下行为实际上可能存在差异:

        int x = 0;
        
        int main() { ... }
        

        int x;
        
        int main() { ... }
        

        如果您使用共享数据段,那么 VC++ 至少使用显式初始化和#pragma data_seg 来确定特定变量应该进入共享数据段还是进程的私有数据段。

        为了增加乐趣,考虑一下如果你有一个静态 C++ 对象,并且在共享数据段中声明了构造函数/析构函数,会发生什么。每次 exe/dll 附加到数据段时都会调用构造函数/析构函数,这几乎可以肯定不是您想要的。

        更多详情请看KB article

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-06-17
          • 2011-02-01
          • 1970-01-01
          • 1970-01-01
          • 2020-09-18
          • 1970-01-01
          • 2021-07-24
          • 1970-01-01
          相关资源
          最近更新 更多