简体   繁体   English

当shared_ptr重置为包含的同一地址时,是否可以保证weak_ptr将过期?

[英]Is it guaranteed that weak_ptr will expire when shared_ptr is reset to the same address that contains?

Is it guaranteed that weak_ptr will expire when shared_ptr is reset to the same address that contains? 当shared_ptr重置为包含的同一地址时,是否可以保证weak_ptr将过期?

#include <cassert>
#include <memory>

int main()
{
    int* i = new int(0);
    std::shared_ptr<int> si( i );
    std::weak_ptr<int> wi = si;

    si.reset( i );

    assert( wi.expired() ); // wi.expired() == true (GCC 4.7)
}

Or is this the case when the value of wi.expired() is not defined? 或者,如果wi.expired()的值,是这种情况吗?

EDIT: 编辑:

I now modify the question little bit: 我现在稍微修改一下这个问题:

Is it guaranteed that weak_ptr will expire when shared_ptr is reset to the same address, which contained a shared_ptr when it was initialized weak_ptr ? shared_ptr被重置为同一个地址时,是否保证weak_ptr将到期,该地址在初始化时包含shared_ptr weak_ptr

#include <cassert>
#include <memory>

int main()
{
    int* i = new int(0);
    std::shared_ptr<int> si( i );
    std::weak_ptr<int> wi = si;

    si.reset();

    int* j = new int(0); 
    // Suppose that new returns the same address that contains variable i :  
    assert(j == i); 

    si.reset( j );

    assert( wi.expired() ); // wi.expired() == true (GCC 4.7)
}

On one side, it actually should. 一方面,它实际应该。 On the other side it's not correct to assign the same pointer to two different shared pointers (si-before-reset and si-after-reset). 另一方面,将相同的指针分配给两个不同的共享指针(si-before-reset和si-after-reset)是不正确的。 In fact, invoking si.reset(i) it happens that: 实际上,调用si.reset(i)它会发生:

  • the ref-count of si drops to 0 si的ref-count降至0
  • delete i is invoked delete i被调用
  • the reborn si points to i again. 再生的si再次指向i

so the newly assigned i after reset will point to not allocated memory, and wi is correctly expired (and will give origin to a segfault when si is gone, eventually, trying to delete i again). 因此,重置后新分配的i将指向未分配的内存,并且wi正确到期(并且当si消失时将导致段错误,最终,再次尝试删除i )。

Good practice is to never reference to the naked pointer after it has been assigned to a shared_ptr. 好的做法是在将裸指针分配给shared_ptr之后永远不要引用它。

ANSWER AFTER EDIT: 编辑后的答案:

The same applies there too: the fact that the pointer is the same has nothing to do with shared_ptr and its internal ref-count. 这同样适用:指针相同的事实与shared_ptr及其内部引用计数无关。 This is maybe clearer with an "evil" example. 对于一个“邪恶”的例子,这可能更清楚。 This is wrong: 这是错的:

  int *i = new int;

  std::shared_ptr<int> si1(i);
  std::shared_ptr<int> si2(i); // deleting twice i on destruction of si2 - boom!
  std::weak_ptr<int> wi1 = si1;

  si1.reset();
  assert (wi1.expired());      // true

this is similar (really the same) of your first example: si1 and si2 are two distinct shared_ptr's (they were si-before-reset and si-after-reset). 这与你的第一个例子类似(实际上是相同的):si1和si2是两个不同的shared_ptr(它们是si-before-reset和si-after-reset)。 The fact that si1 and si2 (wrongly) point to the same memory has nothing to do with the life of the shared_ptr's and of the connected weak_ptr's. 这一事实si1si2 (错误地)指向同一个内存无关用的shared_ptr的寿命和连接的weak_ptr的的。

The absolute value of the i pointer is not used to determine the ref-count. i指针的绝对值不用于确定引用计数。 For both the shared_ptr's and the weak_ptr's. 对于shared_ptr和weak_ptr都是如此。 So yes, it is guaranteed! 所以,是的,保证!

In fact, when you need the shared_ptr of an object from inside its class, you need enable_shared_from_this - If you were using shared_ptr(this) instead of shared_from_this() you were getting different shared_ptr's every time - destroying your object as soon as the first of them had gone out of ref-counts. 实际上,当你需要来自其类中的对象的shared_ptr时,你需要enable_shared_from_this - 如果你使用的是shared_ptr(this)而不是shared_from_this(),那么你每次都会得到不同的shared_ptr - 一旦第一个就破坏你的对象他们已经退出了重新计算。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM