[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