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

Как использовать std:: allocator в моем собственном классе контейнера

Я пытаюсь написать класс контейнера, который использует STL-распределители. То, что я сейчас делаю, это иметь частного участника

std::allocator<T> alloc_;

(это позже будет шаблоном, чтобы пользователь мог выбрать другой распределитель), а затем вызовите

T* ptr = alloc_.allocate(1,0);

чтобы получить указатель на вновь выделенный объект 'T' (и использовать alloc_.construct для вызова конструктора, см. ответ ниже). Это работает с библиотекой GNU С++.

Однако, с STLPort на Solaris, это не позволяет делать правильные вещи и приводит к различным видам ошибок коррупции памяти. Если я вместо этого делаю

std::allocator_interface<std::allocator<T> > alloc_;

тогда все работает так, как должно.

Каков правильный способ использования stl:: allocator? Версия STLPort/Solaris не скомпилирована с g++, но правильно ли g++?

4b9b3361

Ответ 1

Что-то, что вы, возможно, захотите сделать, это иметь собственный пользовательский allocator, который вы можете использовать, чтобы увидеть, как стандартные контейнеры взаимодействуют с распределителями. Стефан Т. Лававей написал красивый, простой, названный mallocator. Бросьте его в тестовую программу, в которой используются различные контейнеры STL, и вы можете легко увидеть, как распределитель используется стандартными контейнерами:

Не все функции интерфейса в mallocator (например, construct() и destroy()) используются для вывода трассировки, поэтому вам может потребоваться отбросить инструкции трассировки, чтобы более легко увидеть, как могут использоваться стандартные контейнеры используйте эти функции, не прибегая к отладчику.

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

Ответ 2

Вам нужно как распределить, так и построить с помощью распределителя. Что-то вроде этого:

T* ptr = alloc_.allocate(1,0);
alloc_.construct(ptr, value);

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