2

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.

Nathan Doromal
  • 3,437
  • 2
  • 24
  • 25

1 Answers1

1

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.

sehe
  • 374,641
  • 47
  • 450
  • 633
  • I think the boost::pool could be superior to the vector because it implicitly takes care of the memory when allocating and deallocating nodes. – Nathan Doromal Sep 19 '14 at 13:24
  • @NathanDoromal what's the difference in that regards with, say, vector or deque? – sehe Sep 19 '14 at 15:22
  • The difference lies when we hit the end of the vector or deque and need to allocate more nodes. Implicitly both use an allocator and both use additional dynamic memory which in of itself is not tracked unless a custom allocator is used. By using Boost pool, I get rid of this extra management and most cleanly handle both the lifetime management and dynamic memory management in one go. – Nathan Doromal Sep 19 '14 at 18:44