Как использовать std::allocator вместо realloc?
Допустим, я пишу собственный вектор, используя std::allocator
обернуть new
а также delete
,
Когда количество элементов превышает емкость вектора, я бы хотел перераспределить буфер на что-то большее. Я могу легко добиться этого, позвонив 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 для переноса new и delete.
В общем случае (исключая специализации для POD), я не думаю, что вы могли бы использовать realloc
в любом случае. Произвольный объект, созданный в определенном месте памяти, может иметь внутренние указатели, указывающие на очень конкретные адреса по отношению к адресу, в котором он был создан. Простое перемещение (в смысле копирования байтов) может нарушить инварианты.
Таким образом, альтернатива, которую вы упоминаете, в целом необходима Вы должны были бы выделить новый массив, move
(или, возможно, даже copy
!) объекты на новое место, затем освободите старый массив. Конечно, это включает в себя более одного этапа, который может потерпеть неудачу - еще одна причина, почему вы не можете на самом деле reallocate
в общем случае. Возможно, это причина того, что распределители никогда не имели такой функциональности в первом случае - для контейнеров на основе массива вы не можете использовать их вообще (хотя вы могли бы использовать их для специализаций POD).