This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Design summary: smart pointers in allocators


"Bob Walters" <bob.s.walters@gmail.com> wrote in message 
3d6744d10808261529o33724bees4071c6e713c7f816@mail.gmail.com">news:3d6744d10808261529o33724bees4071c6e713c7f816@mail.gmail.com...
>I think I've managed to a design for the alternative pointer support
> which can work for varieties of 'smart pointers' as well as pointer
> which represent alternative storage mechanisms.  (Phil, would
> appreciate your feedback on this.)

[...]

I will review the classes in my spare time but the following caught my 
attention.

> g)  the allocator's deallocate() method takes a pointer by value, but
> needs to ensure that all references to that address are cleared.  In
> some cases, the 'cheat' of using a deallocate() method which takes the
> pointer by reference allows the deallocation to occur by setting the
> pointer to null.  As a safety this method can also ensure that the
> pointer passed knows it is responsible for the address being
> deallocated (that ownership = true)
>
> I think the above may have some holes.  Possible.... but very ugly, I
> admit.  I just haven't thought of anything cleaner.  The only other
> alternatives that I've seen are:
> a) don't support smart pointers, require that all memory management be
> done by the allocator as intended by the standard.
> b) redesign some containers (like vector) to avoid the pointer as
> iterator idiom, and generally work to ensure that an
> allocator::pointer only points to a heap allocated address, and so on.
> In my thinking, this is pushing too much responsibility onto the
> containers, and involves far too much impact.
> c) do the container changes with the assumption that
> allocator::pointer is a smart pointer, and has to point to allocated
> memory only.  With vector, this means some internal pointer use
> allocator::pointer, and some remain normal T* to differentiate.
> However, this design then breaks all cases of using alocator::pointer
> for storage reasons (e.g. boost::interprocess::offset_pointer) and I'm
> opposed to this.

I think a redesign will be needed inside the containers because smart 
pointer support is inevitable.  Fortunately I don't think this is a big 
problem outside the clear(node *) and insert(node *) operations.

I think there is a solution towards the approaches we are studying.  The 
problem with having deallocate(smart_ptr &) passing its argument as a 
reference is that this will break an attempt to virtualize allocators:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2387.pdf

There are different solutions we can take which would consist of 
virtualizing the functions returning allocated block, such as (in list<>):
- virtual _List_node<_Tp>* _M_get_node()
- virtual void _M_put_node(_List_node<_Tp>* __p)

But I was considering yet another approach which would have to be well 
tested in terms of usability because it may involve run-time issues.  The 
idea would be to add an implicit convertion function to type "void *" to the 
smart pointer class.  But this operator woudl require giving away its 
ownership of the pointer and returning 0 (nullptr) if the reference count 
isn't yet down to zero:

template <typename T>
    class smart_ptr
    {
        ...
        operator bool () ...
        operator const void * ()
        {
            return -- _M_count ? 0 : _M_p;
        }
    };

At that point the allocator wouldn't even have to worry about the type of 
pointer being passed in because an implicit convertion will occur before the 
function is called:

template <typename T>
    class allocator
    {
        ...
        void deallocate(const void * __p)
        {
            if (__p) ...
        }
    };

This would be very clean but I think supporting smart pointer inside the 
allocator will be safer because the allocator is already aware it's using 
them (typedef smart_ptr<T> pointer).


-Phil




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]