2016-08-02 5 views
3

Предположим, что я пишу пользовательский вектор, используя std::allocator, чтобы обернуть new и delete.Как использовать использование std :: allocator вместо realloc?

Когда количество элементов превышает емкость вектора, я хотел бы перераспределить буфер на нечто большее. Я могу легко достичь этого, позвонив по телефону realloc(). Я не хочу этого делать, потому что я думал, что ответственность за распределение/освобождение должна находиться в распределителе.

Однако, глядя на интерфейс std::allocator, я не вижу, как я мог бы перераспределить. Есть только методы:

T* allocate(std::size_t n); 
void deallocate(T* p, std::size_t n); 

Должен ли я называть allocator::allocate, а затем allocator::deallocate вместо того, чтобы просто realloc? Это так же эффективно? Это должно быть то, что делает std::vector. Почему std::allocator не предоставляет функцию reallocate?

+1

_ «Почему std :: allocator не предоставляет функцию перераспределения?» _ Это частично рассматривается в [этом вопросе] (http://stackoverflow.com/questions/3105001/why-is-there-no-reallocation -functionality-в-с-распределители? RQ = 1). – ArchbishopOfBanterbury

+0

[FYI] https://isocpp.org/wiki/faq/freestore-mgmt#realloc-and-renew – NathanOliver

+1

@NathanOliver. Он заканчивается тем, что «на C++ лучший способ справиться с перераспределением - использовать стандартный контейнер библиотеки , например, вектор, и пусть он растет естественным образом ». Это является отправной точкой для этого вопроса ... –

ответ

4

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

В общем случае (исключая специализации для POD), я не думаю, что вы могли бы использовать realloc в любом случае. У произвольного объекта, построенного в определенном месте памяти, могут быть внутренние указатели, указывающие на очень конкретные адреса по отношению к адресу, в котором он был сконструирован. Простое перемещение (в байтовом смысле) могло бы разбить инварианты.

Таким образом, альтернатива, которую вы упомянули, в общем необходима. Вам нужно будет выделить новый массив, move (или, возможно, даже copy!) Объектов в новое место, а затем освободить старый массив. Конечно, это включает более чем один этап, который может потерпеть неудачу - еще одна причина, по которой вы не можете действительно reallocate в общем случае. Возможно, именно по этой причине у распределителей никогда не было этой функции в первом случае - для контейнеров на основе массивов вы не можете использовать их вообще (хотя вы могли бы использовать их для специализации POD).

 Смежные вопросы

  • Нет связанных вопросов^_^