是否可以确保在将shared_ptr重置为包含的相同地址时,weak_ptr会过期吗? [英] Is it guaranteed that weak_ptr will expire when shared_ptr is reset to the same address that contains?
问题描述
是否可以确保将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_ptr
在shared_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 toi
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). si1
和si2
(错误地)指向相同的内存这一事实与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屋!