Как использовать std::allocator в моем собственном классе контейнера
Я пытаюсь написать контейнерный класс, который использует распределители STL. То, что я в настоящее время делаю, это иметь частного члена
std::allocator<T> alloc_;
(позже это будет шаблонизировано, чтобы пользователь мог выбрать другой распределитель), а затем вызвать
T* ptr = alloc_.allocate(1,0);
чтобы получить указатель на недавно выделенный объект 'T' (и использовал alloc_.construct для вызова конструктора; см. ответ ниже). Это работает с библиотекой GNU C++.
Однако, с STLPort на Solaris, это не дает правильных результатов и приводит к всевозможным причудливым повреждениям памяти. Если я вместо этого
std::allocator_interface<std::allocator<T> > alloc_;
тогда все работает как надо.
Как правильно использовать stl::allocator? Версия STLPort/Solaris не может быть скомпилирована с g++, но подходит ли g ++?
2 ответа
Что-то, что вы можете захотеть сделать, это иметь свой собственный обычай allocator
что вы можете использовать, чтобы увидеть, как стандартные контейнеры взаимодействуют с распределителями. Стефан Т. Лававей опубликовал хороший, простой под названием mallocator
, Перетащите его в тестовую программу, которая использует различные контейнеры STL, и вы можете легко увидеть, как распределитель используется стандартными контейнерами:
Не все интерфейсные функции в mallocator
(такие как construct()
а также destroy()
) снабжены выводом трассировки, поэтому вы можете захотеть добавить туда операторы трассировки, чтобы было проще увидеть, как стандартные контейнеры могут использовать эти функции, не прибегая к отладчику.
Это должно дать вам хорошее представление о том, как ваши контейнеры могут использовать allocator
,
Вы должны как выделить, так и построить с помощью распределителя. Что-то вроде этого:
T* ptr = alloc_.allocate(1,0);
alloc_.construct(ptr, value);
Многие вещи прямо сломаны, если вы не начинаете с правильно построенного объекта. Представь себе std::string
выделяется, но не строится. Когда вы попытаетесь присвоить ему, он сначала попытается очистить свое старое содержимое, освободив некоторые данные, которые, конечно, будут значениями мусора из кучи и сбоями.