Использует ли STL Vector «new» и «delete» для выделения памяти по умолчанию? - PullRequest
9 голосов
/ 12 ноября 2010

Я работаю над плагином для приложения, в котором приложение должно распределять память и следить за ним. Следовательно, дескрипторы памяти должны быть получены из хост-приложения в виде буферов и позже возвращать их в приложение. Теперь я планирую использовать векторы STL и мне интересно, какой тип распределения памяти он использует для внутреннего использования.

Используются ли внутри функции «new» и «delete»? Если да, могу ли я просто перегрузить 'new' и 'delete' своими собственными функциями? Или я должен создать свой собственный распределитель шаблонов, который выглядит для меня как трудная работа, поскольку у меня нет такого опыта в создании пользовательских шаблонов.

Любые предложения / примеры кода приветствуются. Дескрипторы памяти могут быть получены из приложения, как это

void* bufferH = NULL;

bufferH = MemReg()->New_Mem_Handle(size_of_buffer);
MemReg()->Dispose_Mem_Handle(bufferH); //Dispose it

Ответы [ 5 ]

18 голосов
/ 12 ноября 2010

vector использует std::allocator по умолчанию, и std::allocator требуется, чтобы использовать глобальный оператор new (то есть ::operator new(size_t)) для получения памяти (20.4.1.1).Тем не менее, не требуется вызывать его ровно один раз за вызов allocator::allocate.

Так что да, если вы замените глобальный оператор новым, vector будет использовать его, хотя и не обязательно таким способом, который действительнопозволяет вашей реализации эффективно управлять памятью.Любые специальные приемы, которые вы хотите использовать, могут, в принципе, быть совершенно неактуальными, если std::allocator захватить память по 10 МБ и выделить ее.

Если у вас есть конкретная реализация, вы можете посмотреть, какего vector ведет себя, что, вероятно, достаточно хорошо, если ваша запланированная стратегия распределения изначально зависит от платформы.

6 голосов
/ 12 ноября 2010

STL-контейнеры используют распределитель, который они дают во время построения, с распределителем по умолчанию , который использует operator new и operator delete.

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

Я бы сначала измерил производительность, используя значение по умолчанию, и оптимизировал, только если вам действительно нужно. Абстракция распределителя предлагает вам относительно чистый способ точной настройки здесь без серьезного редизайна. То, как вы используете vector, может оказать гораздо большее влияние на производительность, чем базовый распределитель (заранее reserve(), избегайте вставки и удаления в середине диапазона элементов, эффективно обрабатывайте создание элементов при копировании - стандартные предупреждения ).

3 голосов
/ 12 ноября 2010

std::vector использует функции unitialized_* для создания своих элементов из необработанной памяти (с использованием размещения new). Он выделяет хранилище, используя тот распределитель, с которым он был создан, и по умолчанию этот распределитель использует ::operator new(size_t) и ::operator delete(void *p) напрямую (т. Е. Не зависит от типа operator new).

2 голосов
/ 12 ноября 2010

Фактический std::allocator был оптимизирован для довольно большого размера объектов размера.Это не самое лучшее, когда речь идет о распределении множества мелких объектов, и не самое лучшее для многих крупных объектов.Тем не менее, он также не был написан для многопоточных приложений.

Могу ли я предложить, прежде чем пытаться написать свое собственное, вы посмотрите распределитель Hoard , если вы собираетесьмногопоточный маршрут.(Или вы можете посмотреть на столь же привлекательную страницу Intel TBB .)

2 голосов
/ 12 ноября 2010

Из этой статьи «Концепция распределителей была первоначально введена для предоставления абстракции для разных моделей памяти для решения проблемы наличия разных типов указателей в определенных 16-разрядных операционных системах (таких какдалеко и так далее) "...

" Стандарт предоставляет распределитель, который внутренне использует глобальные операторы "new" и "delete" "

Автор также указывает на интерфейс распределителяэто не страшноКак сказал бы Нил Бьюкенен, «попробуй сам!»

...