是否可以确保在将shared_ptr重置为包含的相同地址时,weak_ptr会过期吗? [英] Is it guaranteed that weak_ptr will expire when shared_ptr is reset to the same address that contains?

查看:122
本文介绍了是否可以确保在将shared_ptr重置为包含的相同地址时,weak_ptr会过期吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

#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)
}

还是没有定义wi.expired()的值的情况?

Or is this the case when the value of wi.expired() is not defined?

我现在稍微修改一下问题:

I now modify the question little bit:

是否可以保证weak_ptrshared_ptr重置为相同的地址时会过期,而该地址在初始化weak_ptr时包含一个shared_ptr?

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?

#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)
}

推荐答案

实际上,它应该这样做. 另一方面,将相同的指针分配给两个不同的共享指针(si-before-reset和si-after-reset)是不正确的.实际上,调用si.reset(i)时会发生以下情况:

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). In fact, invoking si.reset(i) it happens that:

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

,因此在重置后新分配的i将指向未分配的内存,并且wi已正确到期(并且在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).

优良作法是在将裸指针分配给shared_ptr之后,再也不要引用裸指针.

Good practice is to never reference to the naked pointer after it has been assigned to a shared_ptr.

编辑后回答:

同样也适用于此:指针相同的事实与shared_ptr及其内部引用计数无关.用邪恶"的例子可能更清楚.这是错误的:

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. 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

这与您的第一个示例类似(实际上是相同的):si1和si2是两个不同的shared_ptr(它们分别是si-before-reset和si-after-reset). si1si2(错误地)指向相同的内存这一事实与shared_ptr以及所连接的weak_ptr的寿命无关.

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). 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.

i指针的绝对值不用于确定引用计数.对于shared_ptr和weak_ptr.是的,这是可以保证的!

The absolute value of the i pointer is not used to determine the ref-count. For both the shared_ptr's and the weak_ptr's. So yes, it is guaranteed!

实际上,当您需要从其类内部获取对象的shared_ptr时,就需要 enable_shared_from_this -如果您使用的是shared_ptr(this)而不是 shared_from_this()您每次都会获得不同的shared_ptr-一旦第一个对象超出引用计数,就会销毁您的对象.

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重置为包含的相同地址时,weak_ptr会过期吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆