全局内存是否在 C++ 中初始化?如果是这样,怎么办?
(二)澄清:
当程序启动时,在初始化原语之前,将成为全局内存的内存空间中有什么?我试图了解它是归零还是垃圾。
instance()
情况是:可以在初始化之前通过调用设置单例引用:
MySingleton* MySingleton::_instance = NULL;
结果得到两个单例实例?
请参阅我关于单例的多个实例的 C++ 测验...
全局内存是否在 C++ 中初始化?如果是这样,怎么办?
(二)澄清:
当程序启动时,在初始化原语之前,将成为全局内存的内存空间中有什么?我试图了解它是归零还是垃圾。
instance()
情况是:可以在初始化之前通过调用设置单例引用:
MySingleton* MySingleton::_instance = NULL;
结果得到两个单例实例?
请参阅我关于单例的多个实例的 C++ 测验...
从标准:
具有静态存储持续时间(3.7.1)的对象应在任何其他初始化发生之前进行零初始化(8.5)。零初始化和用常量表达式初始化统称为静态初始化;所有其他初始化都是动态初始化. 使用常量表达式 (5.19) 初始化的具有静态存储持续时间的 POD [plain old data] 类型 (3.9) 的对象应在任何动态初始化发生之前进行初始化。在同一翻译单元的命名空间范围内定义的静态存储持续时间并动态初始化的对象应按照其定义在翻译单元中出现的顺序进行初始化。[注:8.5.1 描述了聚合成员的初始化顺序。局部静态对象的初始化在 6.7 中描述。]
所以是的,具有静态存储持续时间的全局变量将被初始化。例如,在堆上分配的全局变量当然不会自动初始化。
是的,全局原语被初始化为 NULL。
例子:
int x;
int main(int argc, char**argv)
{
assert(x == 0);
int y;
//assert(y == 0); <-- wrong can't assume this.
}
你不能对堆上的类、结构、数组、内存块做任何假设......
始终初始化所有内容是最安全的。
来自嵌入式世界...
您的代码被编译成三种类型的内存:
1. .data:初始化内存
2..text:常量和代码
3..bss:未初始化内存(如果未显式初始化,则在 C++ 中初始化为 0)
如果初始化,全局变量会进入 .data。如果不是,它们将被放置在 .bss 中并在主代码中归零。
使用静态/全局范围声明的变量总是至少在 VC++ 下初始化。
在某些情况下,实际上可能存在以下行为差异:
int x = 0;
int main() { ... }
和
int x;
int main() { ... }
如果您使用共享数据段,那么 VC++ 至少使用显式初始化和 a#pragma data_seg
来确定特定变量应该进入共享数据段还是进程的私有数据段。
为了增加乐趣,请考虑如果您有一个静态 C++ 对象,并且在共享数据段中声明了构造函数/析构函数,会发生什么。每次 exe/dll 附加到数据段时都会调用构造函数/析构函数,这几乎肯定不是您想要的。
此知识库文章中的更多详细信息