Что такое конструктор по умолчанию для указателя на C ++?

У меня такой код:

class MapIndex { private: typedef std::map Container; Container mapM; public: void add(std::list& values) { if (values.empty()) // sanity check return; std::string s(*(values.begin())); values.erase(values.begin()); if (values.empty()) return; MapIndex *mi = mapM[s]; // add(values); } } 

Главное, что у меня есть, будет ли выражение mapM [s] возвращать ссылку на NULL-указатель, если новый элемент будет добавлен на карту?

Документы SGI говорят следующее: data_type & operator [] (const key_type & k) Возвращает ссылку на объект, связанный с определенным ключом. Если в карте еще нет такого объекта, оператор [] вставляет объект по умолчанию data_type ().

Итак, мой вопрос заключается в том, будет ли вставка объекта по умолчанию data_type () создавать указатель NULL или создать недопустимый указатель, указывающий где-нибудь в памяти?

Он создаст указатель NULL (0), который в любом случае является недопустимым указателем 🙂

Да, он должен быть нулевым (NULL) указателем, так как stl-контейнеры будут инициализировать объекты по умолчанию, если они явно не сохранены (т.е. доступ к несуществующему ключу на карте по мере того, как вы делаете или изменяете размер вектора в большем размере).

Стандарт C ++, пункт 8.5 пункта 5:

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

  • Если T является classом classа non-POD (class предложения), вызывается конструктор по умолчанию для T (и инициализация плохо сформирована, если T не имеет доступного конструктора по умолчанию)
  • Если T – тип массива, каждый элемент инициализируется по умолчанию
  • В противном случае хранилище для объекта iszero-initialized.

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

 int a; // not default constructed, will have random data int b = int(); // will be initialised to zero 

ОБНОВЛЕНИЕ: я завершил свою программу, и эта строка, о которой я спрашивал, вызывает ее иногда, но на более позднем этапе. Проблема в том, что я создаю новый объект без изменения указателя, хранящегося в std :: map. То, что действительно необходимо, является ссылкой или указателем на этот указатель.

 MapIndex *mi = mapM[s]; // <- question about this line if (!mi) mi = new MapIndex(); mi->add(values); 

следует изменить на:

 MapIndex* &mi = mapM[s]; // <- question about this line if (!mi) mi = new MapIndex(); mi->add(values); 

Я удивлен, что никто этого не заметил.

Выражение data_type() оценивается объектом, инициализированным по умолчанию. В случае не-POD-типов вызывается конструктор по умолчанию, но в случае типов POD, таких как указатели, инициализация по умолчанию эквивалентна нулевой инициализации.

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

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

if (! mi) mi = new MapIndex ();

всегда возвращает true, потому что указатель mi не ссылается на то, что mapM удерживает для определенного значения s.

Я бы также избегал использования обычных указателей и использовал boost :: shared_ptr или какой-либо другой указатель, который освобождает память при уничтожении. Это позволяет вызывать mapM.clear () или erase (), которые должны вызывать деструкторы ключей и значений, хранящихся на карте. Ну, если значение POD, например, ваш указатель, тогда никакой деструктор не вызывается для этого, если он не будет удален вручную, а итерация по всей карте приведет к утечке памяти.

  • Создать указатель на двумерный массив
  • Динамический двумерный массив с указателем на указатель
  • В C, являются указателями массивов или используются в качестве указателей?
  • Swift 2 - UnsafeMutablePointer для объекта
  • Исключение для массива, не затухающего в указатель?
  • Объявление указателей; звездочку слева или справа от пространства между типом и именем?
  • Разделение этого указателя дает мне -46, но я не уверен, почему
  • Как я могу получить размер массива из указателя в C?
  • C: указатель на структуру в определении структуры
  • Почему полезен указатель «точка-volatile», например «volatile int * p»?
  • C ++ Возвращаемый массив многомерности из функции
  • Давайте будем гением компьютера.