[GSoC] __enable_shared_from_this_helper

Tim Shen timshen@google.com
Sun May 3 23:47:00 GMT 2015


On Sun, May 3, 2015 at 4:03 PM, Fan You <youfan.noey@gmail.com> wrote:
> Follow up questions:
>
>> > According to my knowledge, __enable_shared_from_this construct a
>> > weak_ptr in order to safely instantiate a new shared_ptr use only this
>> > pointer. So, does __enable_shared_from_this_helper has no effect until
>> > user trying to do something like this?
>> >
>> >> class Test : public ___enable_shared_from_this { };
>> >>
>> >> shared_ptr<Test> (new Test());
>>
>> Correct.
>> It ensures that when an object is owned by a shared_ptr, the weak_ptr
>> member shares ownership with that shared_ptr.
>
> However,
>
> ctor of __shared_count only pass the same type of pointer into
>
>> __enable_shared_from_this_helper(_M_refcount, __p, __p);
>
>
> but __enable_shared_from_this_helper take two different types of ptr.
>
>> (__shared_count&, __enable_shared_from_this* ptr1, _Tp1* ptr2)
>
> Can you give any specific example of using this feature ?
>

You are looking at the wrong overloading. There're three overloadings declared:

  template<_Lock_policy _Lp, typename _Tp1, typename _Tp2>
    void
    __enable_shared_from_this_helper(const __shared_count<_Lp>&,
                     const __enable_shared_from_this<_Tp1,
                     _Lp>*, const _Tp2*) noexcept;

  // Friend of enable_shared_from_this.
  template<typename _Tp1, typename _Tp2>
    void
    __enable_shared_from_this_helper(const __shared_count<>&,
                     const enable_shared_from_this<_Tp1>*,
                     const _Tp2*) noexcept;

  template<_Lock_policy _Lp>
    inline void
    __enable_shared_from_this_helper(const __shared_count<_Lp>&, ...) noexcept
    { }


> 2.
> int* a = new int(1);
> shared_ptr<int> a1(a);
> shared_ptr<int> a2(a);
>
> When user are trying to do some thing like this, should it throw? I've
> tested on the original
> std::shared_ptr in gcc 4.9.2, it will not throw on type like <int> but
> it do throw on array types.
> However, my currently implementation will throw "double deletion" at runtime.
>
> <http://stackoverflow.com/questions/10338606/multiple-shared-ptr-storing-same-pointer>
>

What do you mean by "throw"?

In my GNU/Linux machine, explicit double deletion:

int* a = new int;
delete a;
deleta a;

will cause a glibc double free corruption:
*** Error in `./a.out': double free or corruption (fasttop):
0x0000000002435c20 ***
======= Backtrace: =========
/usr/lib/libc.so.6(+0x7198e)[0x7ff57b05c98e]
/usr/lib/libc.so.6(+0x76dee)[0x7ff57b061dee]
/usr/lib/libc.so.6(+0x775cb)[0x7ff57b0625cb]
./a.out[0x40066a]
/usr/lib/libc.so.6(__libc_start_main+0xf0)[0x7ff57b00b800]
./a.out[0x400569]
======= Memory map: ========
...

But I think the behavior varies in different platforms.

In your example, it *is* a double deletion, even it ends silently (it
does as well on my machine); if you put a `std::cout << _M_ptr <<
"\n";` in _Sp_counted_ptr::_M_dispose, you will see it.

I don't think that shared_ptr needs to do anything here; it's users
responsibility to use it correctly.

> 3. Also, we might also need a specialization for
> enable_shared_from_this in order to use
> shared_from_this() with std::experimental::shared_ptr;

Since enable_shared_from_this depends on weak_ptr, does it make sense
to impelment weak_ptr for array first, then to deal
enable_shared_from_this?


-- 
Regards,
Tim Shen



More information about the Libstdc++ mailing list