Из-за системных ограничений предположим, что я могу выделить память из кучи только один раз (например, с помощью std::allocator
или другого более общего распределителя, совместимого с C++11).
Это единственное выделение займет большой блок памяти. Затем я хочу использовать контейнеры и динамическую память, но все они ограничены ранее выделенным блоком памяти.
Мне удалось написать очень простой аллокатор, который пошагово «отдает» памяти смещением указателя. В этом аллокаторе deallocate
нет операций, и память из блока не возвращается в блок. Очевидно, что можно сделать лучше, чем это. Другими словами, мне нужна управляемая куча.
Повторное использование этой блочной памяти в последовательности является сложной проблемой, поскольку необходимо управлять прерывистыми свободными сегментами, дефрагментацией, (необязательно) потокобезопасностью и т. д.
Как называется этот шаблон? Какое-то время я думал, что это был распределитель пула, но мне кажется, что это относится к чему-то другому (повторному использованию небольших объектов).
Какие функции или стандартные библиотеки C++ я могу использовать для реализации и администрирования такого распределения или, по крайней мере, создать свои собственные без особых усилий?
Я ожидал найти что-то в Boost. Но Boost.Pool — это что-то другое, и похоже, что-то вроде этого реализовано для определенной цели в Boost.Interprocess, но это не кажется простым в использовании, и мне трудно понять это вне их прототипного использования (например, межпроцессная разделяемая память.)
В противном случае самое близкое, что я нашел, это https://www.boost.org/doc/libs/1_41_0/libs/pool/doc/interfaces/pool_alloc.html , но кажется, что ::new
можно вызывать несколько раз.
Пример кода:
int main(){
UserBlockAllocator<double> a(new double[1000], 1000);
{
std::vector<double, UserBlockAllocator<double>> v0(600, a);
} // v0 returns memory to block managed by a
std::vector<double, UserBlockAllocator<double>> v1(600, a);
std::vector<double, UserBlockAllocator<double>> v2(600, a); //out of memory
}