stl_map Implementation Details for Development of Custom Allocator

Umara Dissanayake umaradissa@gmail.com
Thu Aug 29 11:42:00 GMT 2013


Hi Jonathan,

Thanks for your reply.

"To avoid the copy done by get_allocator() the container would have to
store two allocator objects, which would increase the size of some
maps.  The design of the STL assumes copying allocators is relatively
cheap"

This is what I needed to know, exactly WHY this design decision was made.

I was proposing to have two pointers pointing to objects of
Alloc<_Rb_tree_node> and Alloc<value_type>. Forgive my incorrect
terminology I've only been programming in C++ for six months.



If you could indulge me for one more question.

In the code for stl_tree, the member variable _M_impl is used in quite
a number of places, though I cannot seem to be able to find its
initial definition. Has this been defined in some other way than being
included in header files?

Thanks again,

Cheers
Kosala.



On Thu, Aug 29, 2013 at 2:56 PM, Jonathan Wakely <jwakely.gcc@gmail.com> wrote:
> On 29 August 2013 10:04, Umara Dissanayake wrote:
>> Hi Jonathan
>>
>> Thank you very much for your reply
>>
>> However I think there has been a misunderstanding.
>
> I don't think so.  What you show below just repeats what you said in
> your first mail, and I've already answered that.
>
>> In the code of stl_tree.h we find the following two functions to
>> create and destroy nodes
>>
>> 363       _Link_type
>>  364       _M_create_node(const value_type& __x)
>>  365       {
>>  366         _Link_type __tmp = _M_get_node();
>>  367         try
>>  368           { GET_ALLOCATOR().construct(&__tmp->_M_value_field, __x); }
>>  369         catch(...)
>>  370           {
>>  371             _M_put_node(__tmp);
>>  372             __throw_exception_again;
>>  373           }
>>  374         return __tmp;
>>  375       }
>>
>>
>>
>>
>>
>>  387       void
>>  388       _M_destroy_node(_Link_type __p)
>>  389       {
>>  390         GET_ALLOCATOR().destroy(&__p->_M_value_field);
>>  391         _M_put_node(__p);
>>  392       }
>>
>>
>>  350       allocator_type
>>  351       get_allocator() const
>>  352       { return allocator_type(_M_get_Node_allocator()); }
>> //calls templated copy constructor in allocator.
>>  353
>>
>>
>> Why is get_allocator() being called EVERY TIME construct_node and
>> destroy_node are called?  Couldn't the output of get_allocator() be
>> stored in a pointer and be used for future construct_node destroy_node
>> calls?
>
> How do you store a temporary object "in a pointer"?
>
> The calls to _M_get_node() and _M_put_node() need to use
> Alloc<_Rb_tree_node>, so it needs to use both Alloc<_Rb_tree_node> and
> Alloc<value_type>.  To avoid the copy done by get_allocator() the
> container would have to store two allocator objects, which would
> increase the size of some maps.  The design of the STL assumes copying
> allocators is relatively cheap. If the allocator's converting
> constructor template is a hit on performance then it hints that there
> is something wrong with your allocator, it shouldn't be expensive to
> copy.
>
> Anyway, as I said, I've reported a defect which would replace the
> calls to get_allocator() above with calls to _M_get_Node_allocator(),
> so there would be no copy.



More information about the Gcc-help mailing list