Инициализируется ли глобальная память в C++? И если да, то как?
(Второе) пояснение:
Когда программа запускается, что находится в области памяти, которая станет глобальной памятью до инициализации примитивов? Пытаюсь понять, обнулен он ли, или фигня например.
Ситуация такова: можно ли установить одноэлементную ссылку - через вызов instance()
до ее инициализации:
MySingleton* MySingleton::_instance = NULL;
и получить в результате два экземпляра singleton?
См. Мою викторину по C++ по нескольким экземплярам синглтона ...
Да, глобальные примитивы инициализируются значением NULL.
Пример:
int x;
int main(int argc, char**argv)
{
assert(x == 0);
int y;
//assert(y == 0); <-- wrong can't assume this.
}
Вы не можете делать никаких предположений о классах, структурах, массивах, блоках памяти в куче ...
Безопаснее всего всегда инициализировать все.
Бранан, ты не можешь полагаться на это. Стандарт не требует, чтобы нестатические переменные были инициализированы нулем. Большинство компиляторов инициализируют нестатические переменные с помощью нет, поскольку это требует затрат времени выполнения.
Ctor по умолчанию для встроенных типов обнуляет их, однако ctor по умолчанию не вызывается неявно. См., Например, std::pair<int, bool>
для примера инициализации встроенных типов по умолчанию.
Встроенные типы не имеют конструкторов; Они POD. Такие вещи, как «int i = int ();» или int_member () в списке-инициализаторах-членах, которые выглядят как вызовы конструктора, на самом деле называются «инициализацией значения».
Исходя из встроенного мира ...
Ваш код компилируется в три типа памяти:
1. .data: инициализированная память
2. .text: константы и код
3. .bss: неинициализированная память (инициализируется 0 в C++, если не инициализирована явно)
Глобальные переменные помещаются в .data, если они инициализированы. В противном случае они помещаются в .bss и обнуляются в предварительном коде.
Переменные, объявленные со статической / глобальной областью видимости, всегда инициализируются по крайней мере в VC++.
При некоторых обстоятельствах на самом деле может быть разница в поведении между:
int x = 0;
int main() { ... }
и
int x;
int main() { ... }
Если вы используете сегменты общих данных, то VC++ по крайней мере использует наличие явной инициализации вместе с #pragma data_seg
, чтобы определить, должна ли конкретная переменная идти в сегмент общих данных или сегмент частных данных для процесса.
Для дополнительного удовольствия подумайте, что произойдет, если у вас есть статический объект C++ с конструктором / деструктором, объявленным в общем сегменте данных. Конструктор / деструктор вызывается каждый раз, когда exe / dll подключается к сегменту данных, что почти наверняка не то, что вам нужно.
Подробнее в этом Статья в базе знаний
Из стандарта:
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.]
Итак, да, глобальные объекты со статической продолжительностью хранения будут инициализированы. Выделенные глобалы, например, в куче, конечно, не будут инициализированы автоматически.
Я считаю, что вы можете сделать это предположение о y == 0 в C++. Все получает инициализатор по умолчанию, а для числовых типов - 0.