Vir*_*ser 3 c++ pointers c++11
为什么
struct X{};
X x;
X *q = &x;
std::shared_ptr<X> p(&x);
Run Code Online (Sandbox Code Playgroud)
导致错误和
X x;
X *q = &x;
std::shared_ptr<X> p0 = std::make_shared<X>(x);
Run Code Online (Sandbox Code Playgroud)
不会导致运行时错误?
我读到在第一种情况下,我有“两个不同的指针,指向相同的数据,并且其中一个被共享”,
但是我认为在第二种情况下存在相同的情况?
free(): invalid pointer
Run Code Online (Sandbox Code Playgroud)
lub*_*bgr 10
在第一种情况下,x尽管对象的生命周期已在其作用域的结尾处结束,但该对象被删除。在这里,您可以在堆栈和范围内创建一个实例:
X x; // lifetime automatically ends at the end of the scope
Run Code Online (Sandbox Code Playgroud)
然后,您也要求std::shared_ptr控制的地址的生存期x。
std::shared_ptr<X> p(&x); // calls delete at the end of the scope
Run Code Online (Sandbox Code Playgroud)
因此,您两次释放相同的变量,这是未定义的行为。在第二种情况下,您将创建一个std::shared_ptr独立于x实例的复制实例。
std::shared_ptr<X> p0 = std::make_shared<X>(x); // Copies x, then deletes the copy
Run Code Online (Sandbox Code Playgroud)
没问题,因为两个对象都只删除一次。
请注意std::make_shared此处的语义:传递给它的参数将转发到其模板参数的构造函数。因此,您将触发编译器生成的副本构造函数X(const X&)被调用。这与从std::shared_ptr已经存在的指针创建到via的方式非常不同std::shared_ptr p(&x);。
在第一种情况下,p拥有的所有权x。当p超出范围时,它将删除x。但是x没有动态分配。哎呀。
在第二种情况下,您没有这种情况。该make_shared函数动态分配一个新的共享对象。当p0超出范围时,它将破坏该新创建的对象。注意,在这种情况下,*p0不是x新对象。