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