calloc(), malloc() против создания новой структуры, внутри которой есть unordered_map

Я создаю структуру с полем unordered_map в куче. Когда я использую новый, я могу добавить к нему без проблем. Но с calloc я получаю сообщение об ошибке при вставке, потому что размер корзины равен 0. Он отлично работает после того, как я вызываю резерв.

Итак, когда calloc вызывается для структуры, не запускается ли конструктор unordered_map? Я смущен, почему, если он был в новой структуре, он, кажется, имеет ненулевой размер ведра. И есть ли лучший способ сделать это, кроме вызова резерва? (В этом случае я не могу использовать удаление, поэтому мне нужно придерживаться вызова calloc)


person jamesatha    schedule 11.04.2013    source источник
comment
Почему вы вынуждены использовать calloc?   -  person Pubby    schedule 11.04.2013
comment
это устаревший код. Я просто добавляю к нему новое поле, которое оказывается неупорядоченной картой.   -  person jamesatha    schedule 11.04.2013
comment
Справедливо. Я полагаю, это означает, что вы также не можете использовать новое размещение?   -  person Pubby    schedule 11.04.2013


Ответы (3)


Вы правы, malloc() и др. не запускают конструкторы, а new делают.

Вы не можете полагаться на тот факт, что вызов reserve() после calloc() решит проблему. Это не так. Поведение вашего кода по-прежнему не определено, и он может взорваться в любой момент и в любой момент. как угодно.

Один из способов решить эту проблему — использовать размещение new для вызова конструктора unordered_map.

В качестве альтернативы вы можете превратить поле в указатель, calloc() в struct, а затем использовать new для выделения и создания unordered_map. Если вы сделаете это, вам придется вручную delete это сделать.

person NPE    schedule 11.04.2013

Функции выделения памяти C обычно не вызывают конструкторы. См. раздел malloc и новый. Первый ответ довольно хорошо подводит итог: не используйте malloc в C++.

person Martin Törnwall    schedule 11.04.2013
comment
Обычно? Они никогда не вызовут конструктор. (ну, char может быть единственным исключением) - person Pubby; 11.04.2013
comment
Поскольку я не могу знать поведение каждой реализации, я обычно придерживался. - person Martin Törnwall; 11.04.2013

calloc ничего не делает для инициализации ваших объектов как объектов. По сути, он передает вам указатель на некоторую память, заполненную нулями. Таким образом, любые внутренние поля, требующие инициализации, такие как ваша карта, не получают ее. Вы не должны использовать calloc в сочетании с объектами (на самом деле, вам, вероятно, это вообще не нужно).

person Andrew Lazarus    schedule 11.04.2013