unordered_set, like other node-based hash tables, actually uses two allocators (both obtained by rebinding from the allocator you supply as the template parameter)
One allocator is used to allocate the nodes (in gnu libstdc++ they have type
std::__detail::_Hash_node<T, false>
, in llvm libc++
std::__1::__hash_node<T, void *>
). It is always called to allocate/deallocate just one node at a time, once per single-value insert.
The other to allocate buckets (in gnu libstdc++, a bucket is a pointer of type
std::__detail::_Hash_node_base*
, in llvm libc++, pointer of type
std::__1::__hash_node_base<std::__1::__hash_node<T, void *> *> *
). This second allocator is called to allocate the entire bucket array, once per resize.
The call to unordered_set::reserve allocates the bucket arrays, it makes the call to the second allocator, but does not pre-allocate any nodes. They can indeed benefit greatly from a monotonic pool allocator (same as any other node-based container really), since all nodes have fixed size.
So believe that as soon as I call "clear" the memory is completely deallocated, right? |
When you call clear, the first allocator is called for every node in the set. The second allocator is not called (capacity does not change)
Sounds like the allocator you found online has bugs