2
votes

I understand that boost intrusive collections ultimately store references to the objects and thus that objects need their own lifetime management.

I was wondering if I can simply use boost pool to manage that lifetime. When I want to store a new object in boost intrusive list, could I just allocate an object from boost pool and store it within the list? Then when I delete from the list then I deallocate using boost pool.

1

1 Answers

1
votes

The answer is yes.

It's also not very typical.

If you want to control when and where memory is allocated, you use a pool.

If you want to decouple the memory layout of your datastructure and it's semantics, you use an intrusive container.

So, there is a sweet spot, but it would look more like:

  • decorate element type with intrusive hooks (e.g. for intrusive map)
  • you create new elements in some type of "optimal" memory layout (this could well be a vector<MyElement, custom_allocator>)

Loose remarks:

  • then when I delete from the list then I deallocate using boost pool

    A typical scenario for using a pool is expressly when you want to /not/ have to deallocate the elements (beware of non-trivial destructors). Otherwise, you just move the inefficiencies of the heap local to the pool (fragmentation, locking)

  • the objects need their own lifetime management

    This sounds slightly off. In fact, the object need not have "their own" lifetime management. It's just that their lifetime isn't governed by the intrusive data structure they participate in.

    E.g. by storing all elements in a vector, you get contiguous storage and the lifetime of all the elements is governed by the vector[1]. Hence you can decouple element lifetime and allocation from the container semantics


[1] any issues surrounding vector reallocation are usually prevented by reserving enough capacity up front. If you do, you will realize this is very very similar to a fixed-size pool allocator, but with the added guarantee of zero fragmentation. If you didn't need the latter, you could do a list<T, pool_allocator<T> > so you get locality of reference but stable references on insertion/deletion. Etc. etc.