https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123582

--- Comment #2 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Thomas Schwinge from comment #0)
> Consider constructing an (empty) unordered associative container 'c'
> ('std::unordered_map', 'std::unordered_multimap', 'std::unordered_multiset',
> 'std::unordered_set'), and then gradually populating it, which dynamically
> has to allocate memory for the hash table as well as the nodes.
> 
> I understand that 'clear()' doesn't necessarily have to deallocate all that
> memory, but my assumption is that when overwriting such an unordered
> associative container 'c' with a pristine instance: 'c = {};', then all
> memory of 'c' should get deallocated?

No, because that is not a "pristine instance", it's an empty initializer_list,
i.e. equivalent to:

c = std::initializer_list<T>{};

This just says "replace the current elements with zero elements".

> I have not yet properly debugged
> this, but it appears as if the latter also only deallocates memory for the
> nodes, but not for the hash table?  Is this intentional?

Yes, definitely.

>  Is there a way to
> completely clear out an unordered associative container (other than
> destructing it)?

You can swap with a default-constructed temporary, which will restore it to a
default-constructed state.

Cont{}.swap(c);

You can usually get the same effect by move-assigning an empty object (although
depending on the properties of the container's Allocator parameter, move
assignment and swap might work differently):

c = Cont();

This really does assign a new instance of the type, which is not the same as
assigning an empty initializer_list. One is a whole container, the other is
just a syntactic notation for "this list of values".

Reply via email to