Является ли глобальная память инициализирована на С++?
Является ли глобальная память инициализирована на С++? И если да, то как?
(Второе) разъяснение:
Когда программа запускается, что находится в пространстве памяти, которое станет глобальной памятью, до инициализации примитивов? Я пытаюсь понять, если он обнулен или мусор, например.
Ситуация такова: можно задать одноэлементную ссылку - через вызов 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