http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58659
Bug ID: 58659 Summary: Construction of shared_ptr from unique_ptr mismatches new/delete and std::allocator for __shared_ptr_count Product: gcc Version: 4.8.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: spencer at starscale dot com CC: jwakely.gcc at gmail dot com Using gcc-4.8.1 configured with --enable-threads=single --enable-libstdcxx-allocator=mt, I'm seeing the following tiny program crash: int main() { std::unique_ptr<X> u = std::unique_ptr<X>(new X); std::shared_ptr<X> s(std::move(u)); return 0; } Note that I am using a different default std::allocator base class (not new/delete). I think the bug is that the shared_ptr count object is being allocated with new and deleted with std::allocator. This will work when std::allocator is new/delete, but not otherwise. I haven't had time to prove it or work up a patch yet; I can if that helps: please let me know. Look at __shared_ptr_base's __S_create_from_up: template<typename _Tp, typename _Del> static _Sp_counted_base<_Lp>* _S_create_from_up(std::unique_ptr<_Tp, _Del>&& __r, typename std::enable_if<!std::is_reference<_Del>::value>::type* = 0) { typedef typename unique_ptr<_Tp, _Del>::pointer _Ptr; return new _Sp_counted_deleter<_Ptr, _Del, std::allocator<void>, _Lp>(__r.get(), __r.get_deleter()); } It always uses "new" to allocate an _Sp_counted_deleter (in both overloads). I think this is the bug, because _Sp_counted_deleter always uses std::allocator to dispose of itself: virtual void _M_destroy() noexcept { typedef typename allocator_traits<_Alloc>::template rebind_traits<_Sp_counted_deleter> _Alloc_traits; typename _Alloc_traits::allocator_type __a(_M_del); _Alloc_traits::destroy(__a, this); _Alloc_traits::deallocate(__a, this, 1); } CC Jonathan Wakely who has already analyzed this with a test case for the stock std::allocator on the mailing list.