从此指针创建共享指针

时间:2017-09-30 11:31:56

标签: c++11 shared-ptr undefined-behavior

下面的代码给出了预期的分段错误。

struct B{
    shared_ptr<B> createShared(){ return shared_ptr<B>(this);}
};

int main()
{
    shared_ptr<B> p1 = make_shared<B>();
    shared_ptr<B> p2 = p1->createShared();
    return 0;
}

但是当我更改代码时

shared_ptr<B> p1 = make_shared<B>();
        to
shared_ptr<B> p1(new B);

程序编译并运行而不会发生任何崩溃。

有人可以解释一下导致这两种情况之间行为改变的确切原因。

注意: - 我知道这不是从这个指针创建共享指针的正确方法,我正在寻找的是这两种情况之间行为改变的原因。我使用的编译器是clang ++ - 3.8和g ++ - 5.4。

1 个答案:

答案 0 :(得分:0)

在没有崩溃的情况下运行并不意味着您的程序是正确的。当您点击未定义的行为时,结果是未定义的。程序的两个版本都会销毁同一个对象两次,因为您基本上是从同一个原始指针创建两个单独的shared_ptrs。因此,其中一个尝试删除导致未定义行为的无效指针。

创建shared_ptr的两种方法实际上存在差异。让我们考虑shared_ptr<B> p1(new B);,首先分配一个B,然后将raw_ptr初始化为原始ptr为B.在shared_ptr初始化期间,分配一个包含使用计数和同步对象的控制块。这是两个单独的分配。然而,make_shared分配一个足够大的块来保存控制块和实际对象,因此生成的内存布局稍有不同,清理代码也会略有不同。

正如一些程序员提到的那样,你应该使用std::enable_shared_from_this