一个简单的std :: shared_ptr构造案例的段错误

Hon*_*hen 4 c++ memory-management smart-pointers shared-ptr c++11

cppreference我了解到有一个构造函数std::shared_ptr:

template< class Y > explicit shared_ptr( Y* ptr );
Run Code Online (Sandbox Code Playgroud)

我尝试了一段代码如下:

#include <string>
#include <memory>
#include <iostream>

int main(void) {
  /// block 1
  {
    std::shared_ptr<std::string> s1(new std::string("good"));
    std::shared_ptr<std::string> s2(s1.get()); /// s2
    std::cerr << s2.use_count() << std::endl;
  }
  /// block 2
  {
    std::shared_ptr<int> i1(new int(1));
    std::shared_ptr<int> i2(i1.get());  ///  i2
    std::cerr << i2.use_count() << std::endl;
  }
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

它导致块1的段故障,但不是块2,但两者use_count都是1.我可以想到的差异是,它intstd::string由分配器管理的原始类型.

我读bits/shared_ptr.hgcc-4.9,并发现有这种构造一个后置条件:

use_count() == 1 && get() == __p
Run Code Online (Sandbox Code Playgroud)

问题1:

不应该std::shared_ptr使用另一个智能指针引用的原始指针构造?从这个意义上讲,使用此构造函数的首选方法如下所示?

std::shared_ptr<T>(new T(...));
Run Code Online (Sandbox Code Playgroud)

问题2:

标准是否明确要求此构造函数,或者此帖子条件仅适用于libstdc++

Rob*_*ahy 8

这两种情况都是无效的std::shared_ptr.

您不能将相同的原始指针传递给两个 std::shared_ptr构造函数,并期望定义明确的结果. 两个人 std::shared_ptr都会相信他们拥有该指针,并且当他们超出范围时会尝试删除它.

这是双重免费,无效.

如果你想拥有两个std::shared_ptr管理同一个对象的s,你可以用一个原始指针构建其中一个(或者,更好的是,使用std::make_shared),然后从第一个复制构造/分配第二个.这样,内存只能被释放(和解雇的对象的析构)当最后那些std::shared_ptr情愿的超出范围.

你在第一种情况下获得分段错误的原因,而不是第二种情况,可能是因为它int是一个微不足道的类型,因此你不是通过一个释放的指针来运行析构函数int,因为它没有有一个.