Нулевой распределитель по умолчанию обнуляет 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.