Глобальная память инициализируется в C ++? - PullRequest
13 голосов
/ 13 сентября 2008

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

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

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

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

MySingleton* MySingleton::_instance = NULL;

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

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

Ответы [ 4 ]

18 голосов
/ 13 сентября 2008

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

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

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

8 голосов
/ 13 сентября 2008

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

Пример:

int x;

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

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

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

6 голосов
/ 13 сентября 2008

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

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

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

0 голосов
/ 13 сентября 2008

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

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

int x = 0;

int main() { ... }

и

int x;

int main() { ... }

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...