Нулевой распределитель по умолчанию обнуляет int?

При использовании контейнеров STL я не уверен, был ли обнулен int, выделенный распределителем по умолчанию. Следующий код указывает "да" на вопрос:

#include <map>
#include <iostream>

int main() {
  using namespace std;
  map<int, int> m;
  cout << m[1234] << endl;
}

Поскольку ни один документ не подтвердил это, я не смею принимать это как должное.

4 ответа

Решение

Вы увидите, внутри реализации std::map::operator[], если элемент не найден в индексе, вставляется новый и возвращается:

ReturnValue = this->insert(where, make_pair(key_value, mapped_type()));

где mapped_type это второй тип, в вашем случае int, Так что да, по умолчанию инициализируется 0, так как он вставлен как mapped_type(),

Стандарт гарантирует, что объекты, созданные в результате использования оператора индекса, создаются по умолчанию. Обнуляет ли конструктор по умолчанию для какого-либо конкретного класса членов, которые вы ожидаете обнулить, зависит от класса. Для классов без конструкторов члены конструируются по умолчанию, и базовые типы конструирования по умолчанию равны нулю для их версии.

Обратите внимание, это не имеет ничего общего с распределителями!... и вполне безопасно предположить, что распределители tbe оставляют память нетронутой, за исключением, возможно, выделенных распределителей отладки (или распределителей, написанных людьми, которые считают, что обнуление памяти может быть хорошей вещью, а не устройством, скрывающим ошибки). ... и распределитель отладки не обнуляет память, а заполняет ее распознаваемым шаблоном (например, приводит к 0xdeadbeef при просмотре в шестнадцатеричном виде).

Может быть так: 8.5.5 Инициализаторы C++ Стандарт - ANSI ISO IEC 14882 2003

Инициализация нуля объекта типа T означает: если T является скалярным типом (3.9), объекту присваивается значение 0 (ноль), преобразованное в T;

Похоже, что шаблон распределителя по умолчанию будет использовать new int() по умолчанию инициализировать int в 0 в соответствии со стандартом C++ ISO 14882:2003. Глава 8.5, пункт 5,7:

Инициализация нуля объекта типа T означает:

  • если T - скалярный тип (3.9), объекту присваивается значение 0 (ноль), преобразованное в T;

Инициализировать значение объекта типа T означает:

  • если T является типом класса (раздел 9) с конструктором, объявленным пользователем (12.1), то вызывается конструктор по умолчанию для T (и инициализация некорректна, если у T нет доступного конструктора по умолчанию);

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

  • если T является типом массива, то каждый элемент инициализируется значением;

  • в противном случае объект инициализируется нулями

По умолчанию инициализировать объект типа T означает:

  • если T является типом класса, отличным от POD (пункт 9), вызывается конструктор по умолчанию для T (и инициализация является некорректной, если у T нет доступного конструктора по умолчанию);

  • если T является типом массива, каждый элемент инициализируется по умолчанию;

  • в противном случае объект инициализируется нулями.

Объект, инициализатором которого является пустой набор скобок, т. Е. (), Должен быть инициализирован значением.

Есть также похожие правила в проекте стандарта C++11 ISO.

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