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

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

(Второе) пояснение:

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

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

MySingleton* MySingleton::_instance = NULL;

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

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

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
15
0
7 391
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий

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

Пример:

int x;

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

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

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

Я считаю, что вы можете сделать это предположение о y == 0 в C++. Все получает инициализатор по умолчанию, а для числовых типов - 0.

Branan 18.09.2008 20:59

Бранан, ты не можешь полагаться на это. Стандарт не требует, чтобы нестатические переменные были инициализированы нулем. Большинство компиляторов инициализируют нестатические переменные с помощью нет, поскольку это требует затрат времени выполнения.

Derek Park 19.09.2008 01:17

Ctor по умолчанию для встроенных типов обнуляет их, однако ctor по умолчанию не вызывается неявно. См., Например, std::pair<int, bool> для примера инициализации встроенных типов по умолчанию.

fbrereto 01.09.2009 02:41
Редактировать This answer is wrong - you cannot make any assumptions about default initializations of non-static storage by the compiler unless you have a compiler flag that guarantees initialization to zero.
Nick Bastin 01.09.2009 02:44

Встроенные типы не имеют конструкторов; Они POD. Такие вещи, как «int i = int ();» или int_member () в списке-инициализаторах-членах, которые выглядят как вызовы конструктора, на самом деле называются «инициализацией значения».

me22 10.09.2009 22:00

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

Ваш код компилируется в три типа памяти:
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.]

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

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