Is global memory initialized in C++?

2019-01-06 22:23发布

问题:

Is global memory initialized in C++? And if so, how?

(Second) clarification:

When a program starts up, what is in the memory space which will become global memory, prior to primitives being initialized? I'm trying to understand if it is zeroed out, or garbage for example.

The situation is: can a singleton reference be set - via an instance() call, prior to its initialization:

MySingleton* MySingleton::_instance = NULL;

and get two singleton instances as a result?

See my C++ quiz on on multiple instances of a singleton...

回答1:

Yes global primitives are initialized to NULL.

Example:

int x;

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

You cannot make any assumptions about classes, structs, arrays, blocks of memory on the heap...

It's safest just to always initialize everything.



回答2:

From the standard:

Objects with static storage duration (3.7.1) shall be zero-initialized (8.5) before any other initialization takes place. Zero-initialization and initialization with a constant expression are collectively called static initialization; all other initialization is dynamic initialization. Objects of POD [plain old data] types (3.9) with static storage duration initialized with constant expressions (5.19) shall be initialized before any dynamic initialization takes place. Objects with static storage duration defined in namespace scope in the same translation unit and dynamically initialized shall be initialized in the order in which their definition appears in the translation unit. [Note:8.5.1 describes the order in which aggregate members are initialized. The initial- ization of local static objects is described in 6.7.]

So yes, globals which have static storage duration will be initialized. Globals allocated, e.g., on the heap will of course not be initialized automatically.



回答3:

Coming from the embedded world...

Your code gets compiled into three types of memory:
1. .data: initialized memory
2. .text: constants and code
3. .bss: uninitialized memory (initialized to 0 in C++ if not explicitly initialized)

Globals go in .data if initialized. If not they are placed in .bss and zero'ed in premain code.



回答4:

Variables declared with static/global scope are always initialized under VC++ at least.

Under some circumstances there can actually be a difference in behaviour between:

int x = 0;

int main() { ... }

and

int x;

int main() { ... }

If you are using shared data segments then VC++ at least uses the presence of an explicit initialization along with a #pragma data_seg to determine whether a particular variable should go in the shared data segment or the private data segment for a process.

For added fun consider what happens if you have a static C++ object with constructor/destructor declared in a shared data segment. The constructor/destructor is called every time the exe/dll attaches to the data segment which is almost certainly not what you want.

More details in this KB article