Как использовать std :: allocator в моем собственном классе контейнера - PullRequest
20 голосов
/ 24 марта 2010

Я пытаюсь написать контейнерный класс, который использует распределители 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 ]

16 голосов
/ 24 марта 2010

Вам нужно как распределить, так и построить с помощью распределителя. Примерно так:

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

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

9 голосов
/ 24 марта 2010

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

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

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

...