Распределитель C ++ STL против оператора new

Согласно C ++ Primer 4th edition, стр. 755, есть примечание:

Современные программы на C ++ обычно должны использовать класс распределителя для выделения памяти. Это безопаснее и гибче.

Я не совсем понимаю это утверждение. Пока что все материалы, которые я читал, учат использовать new для выделения памяти в C ++. Пример того, как векторный класс использует распределитель, показан в книге. Однако я не могу думать о других сценариях.

Может ли кто-нибудь помочь прояснить это утверждение? и дайте мне еще примеры? Когда мне следует использовать распределитель, а когда - new? Спасибо!


person Ivan Xiao    schedule 11.04.2011    source источник


Ответы (2)


Для общего программирования да, вы должны использовать new и delete.

Однако, если вы пишете библиотеку, этого не следует делать! У меня нет вашего учебника, но я полагаю, что в нем обсуждаются распределители в контексте написания библиотечного кода.

Пользователи библиотеки могут захотеть контролировать, что именно и откуда распределяется. Если бы все распределения библиотеки прошли через new и delete, у пользователя не было бы возможности получить этот мелкозернистый уровень управления.

Все контейнеры STL принимают необязательный аргумент шаблона распределителя. Затем контейнер будет использовать этот распределитель для своей внутренней памяти. По умолчанию, если вы опустите распределитель, он будет использовать std::allocator, который использует new и delete (в частности, ::operator new(size_t) и ::operator delete(void*)).

Таким образом, пользователь этого контейнера может при желании контролировать, откуда выделяется память.

Пример реализации настраиваемого распределителя для использования с STL и объяснение: Повышение производительности с помощью настраиваемых распределителей пула для STL

Дополнительное примечание: Подход STL к распределителям неоптимален по нескольким причинам. Я рекомендую прочитать На пути к лучшей модели распределителя для обсуждения некоторых из этих вопросов.

Изменить в 2019 году: Ситуация в C ++ улучшилась с момента написания этого ответа. Распределители с отслеживанием состояния поддерживаются в C ++ 11, и эта поддержка была улучшена в C ++ 17. Некоторые из людей, участвовавших в «На пути к лучшей модели распределения», были вовлечены в эти изменения (например: N2387), так что приятно (:

person jwd    schedule 11.04.2011
comment
+1 для STL-подхода к распределителям неоптимален плюс ссылка на Towards a Better Allocator Model :) - person Paul Groke; 12.04.2011
comment
Ссылка, которую вы предоставили, очень полезна! - person Ivan Xiao; 14.04.2011

Эти два понятия не противоречат друг другу. Распределители - это PolicyPattern или StrategyPattern, используемые адаптерами контейнеров библиотек STL для выделения фрагментов памяти для использования с объектами.

Эти распределители часто оптимизируют выделение памяти, позволяя сразу выделять * диапазоны элементов, а затем инициализировать их с помощью размещения новые * элементы, выбираемые из вторичных специализированных куч в зависимости от размера блока.

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


Другой яркий пример - как, например, В библиотеке boost реализованы смарт-указатели. Поскольку смарт-указатели очень малы (с небольшими накладными расходами), накладные расходы на выделение ресурсов могут стать обузой. Для реализации было бы разумно определить специализированный распределитель для выполнения распределений, чтобы можно было иметь эффективные std :: set ‹> smartpointers, std :: map‹ ..., smartpointer> и т. Д.

(Теперь я почти уверен, что boost действительно оптимизирует хранилище для большинства интеллектуальных указателей, избегая любых виртуальных машин, поэтому vft, делая класс структурой POD, с только необработанным указателем в качестве хранилища; некоторые из примеров не будут применяться. Но опять же , экстраполировать на другие виды смарт-указателей (счетчик ссылок, указатели на функции-члены, указатели на функции-члены со ссылкой на экземпляр и т. д.))

person sehe    schedule 11.04.2011