Подтвердить что ты не робот

С++ STL allocator vs operator new

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

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

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

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

4b9b3361

Ответ 1

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

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

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

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

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

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

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

Ответ 2

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

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

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


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

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