Является ли глобальная память инициализирована на С++?

Является ли глобальная память инициализирована на С++? И если да, то как?

(Второе) разъяснение:

Когда программа запускается, что находится в пространстве памяти, которое станет глобальной памятью, до инициализации примитивов? Я пытаюсь понять, если он обнулен или мусор, например.

Ситуация такова: можно задать одноэлементную ссылку - через вызов instance() до ее инициализации:

MySingleton* MySingleton::_instance = NULL;

и получить в результате два экземпляра singleton?

Посмотрите мою викторину на С++ в нескольких экземплярах одного...

Ответ 1

Да, глобальные примитивы инициализируются значением NULL.

Пример:

int x;

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

Вы не можете делать какие-либо предположения о классах, структурах, массивах, блоках памяти в куче...

Это безопасно только для того, чтобы всегда инициализировать все.

Ответ 2

Из стандарта:

Объекты со статической продолжительностью хранения (3.7.1) должны быть инициализированы нулями (8.5) перед любой другой инициализацией. Нулевая инициализация и инициализация с постоянным выражением коллективно называются статической инициализацией; вся другая инициализация - это динамическая инициализация. Объекты типов POD [plain old data] (3.9) со статической продолжительностью хранения, инициализированными постоянными выражениями (5.19), должны быть инициализированы до начала любой динамической инициализации. Объекты со статической продолжительностью хранения, определенные в области пространства имен в одной и той же системе перевода и динамически инициализированной, должны быть инициализированы в том порядке, в котором их определение появляется в блоке перевода. [Примечание: 8.5.1 описывает порядок инициализации элементов агрегата. Начальный- ization локальных статических объектов описывается в 6.7.]

Итак, да, глобальные переменные, у которых есть статическая память, будут инициализированы. Глобалы, выделенные, например, в куче, конечно, не будут автоматически инициализированы.

Ответ 3

Исходя из встроенного мира...

Ваш код скомпилирован в три типа памяти:
 1..data: инициализированная память
 2..text: константы и код
 3..bss: неинициализированная память (инициализируется до 0 в С++, если явно не инициализирована)

Глобалы входят в .data, если они инициализированы. Если нет, они помещаются в .bss и zero'ed в предварительном коде.

Ответ 4

Переменные, объявленные со статической/глобальной областью, всегда инициализируются по крайней мере в VС++.

При некоторых обстоятельствах на самом деле может быть разница в поведении между:

int x = 0;

int main() { ... }

и

int x;

int main() { ... }

Если вы используете разделяемые сегменты данных, то VС++ по крайней мере использует наличие явной инициализации вместе с #pragma data_seg, чтобы определить, должна ли конкретная переменная перемещаться в сегменте разделяемых данных или сегменте частных данных для процесса.

Для дополнительного удовольствия подумайте, что произойдет, если у вас есть статический объект С++ с конструктором/деструктором, объявленным в разделяемом сегменте данных. Конструктор/деструктор вызывается каждый раз, когда exe/dll присоединяется к сегменту данных, который почти наверняка не то, что вы хотите.

Подробнее в этом статья в KB