Вопрос

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

(Второе) уточнение:

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

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

MySingleton* MySingleton::_instance = NULL;

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

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

Это было полезно?

Решение

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

Пример:

int x;

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

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

Безопаснее всего всегда все инициализировать.

Другие советы

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

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

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

Выходец из встроенного мира...

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

Глобалы попадают в .data, если они инициализированы.В противном случае они помещаются в .bss и обнуляются в премейн-коде.

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

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

int x = 0;

int main() { ... }

и

int x;

int main() { ... }

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

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

Подробнее в этом статья базы знаний

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top