C++ 简单std::shared_ptr构造案例的段故障

C++ 简单std::shared_ptr构造案例的段故障,c++,c++11,memory-management,shared-ptr,smart-pointers,C++,C++11,Memory Management,Shared Ptr,Smart Pointers,从中我了解到,std::shared\u ptr有一个构造函数: template< class Y > explicit shared_ptr( Y* ptr ); 问题1: std::shared_ptr是否应该使用另一个智能指针引用的原始指针构造?从这个意义上讲,使用这个构造函数的首选方法是什么 std::shared_ptr<T>(new T(...)); std::shared_ptr(新T(…); 问题2: 标准是否对此构造函数有明确的要求,或者此pos

从中我了解到,
std::shared\u ptr
有一个构造函数:

template< class Y > explicit shared_ptr( Y* ptr );
问题1:
std::shared_ptr
是否应该使用另一个智能指针引用的原始指针构造?从这个意义上讲,使用这个构造函数的首选方法是什么

std::shared_ptr<T>(new T(...));
std::shared_ptr(新T(…);
问题2:
标准是否对此构造函数有明确的要求,或者此post条件仅适用于
libstdc++

这是未定义的行为,我们可以通过访问CPP参考部分了解这一点(我的重点):

使用对象的原始指针重载构造共享的\u ptr 已由共享ptr管理的行为会导致未定义的行为, 即使对象的类型是从 std::从这个(换句话说,原始指针重载)启用共享 承担指向对象的所有权)

shared\u ptr
都将尝试删除他们认为现在拥有唯一所有权的对象。我们知道这是未定义的行为,通过C++标准章节草案>代码> 3.7.4.2 < /代码>去重函数,它表示:

如果标准中给定给解除分配函数的参数 库是不是空指针值(4.10)的指针 解除分配功能应解除分配 指针,呈现无效的所有指针,这些指针引用 解除分配存储。通过无效指针值进行间接寻址,并且 将无效指针值传递给解除分配函数的操作失败 未定义的行为。[…]

所有权只能通过使用副本构造或副本分配来共享。相同的cppreference页面提供了使用复制构造函数的正确示例:

use_count() == 1 && get() == __p
 std::cout << "constructor with object\n";
 std::shared_ptr<Foo> sh2(new Foo);
 std::shared_ptr<Foo> sh3(sh2);     // <- using copy construction

std::cout这两种情况都是对
std::shared\u ptr
的无效使用

您不能将相同的原始指针传递给两个
std::shared_ptr
构造函数,并期望得到定义良好的结果两个
std::shared_ptr
都将认为他们拥有该指针,并在超出范围时尝试删除该指针

这是一个双重自由,是无效的

如果希望有两个
std::shared_ptr
s管理同一对象,可以使用原始指针构造其中一个(或者更好地使用),然后从第一个指针复制构造/分配第二个指针。这样,只有当
std::shared_ptr
s中的最后一个超出范围时,才会释放内存(并触发对象的析构函数)


在第一种情况下,而不是在第二种情况下,出现分段错误的原因可能是因为
int
是一种普通类型,因此您没有通过释放的指针运行
int
的析构函数,因为它没有。

构造函数无法知道原始指针是否来自
std::shared\u ptr
,因此它拥有所有指针。在这两种情况下都会导致双重删除,因为两个智能指针拥有同一指针的所有权。很抱歉,我没有阅读该说明,也很抱歉问了这个问题。@HongxuChen没有必要道歉,您不理解语义,问了一个问题。你现在有你的答案了。
 std::cout << "constructor with object\n";
 std::shared_ptr<Foo> sh2(new Foo);
 std::shared_ptr<Foo> sh3(sh2);     // <- using copy construction