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)
}
Or is this the case when the value of wi.expired()
is not defined?
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
?
#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). In fact, invoking si.reset(i)
it happens that:
- the ref-count of
si
drops to 0
delete i
is invoked
- the reborn
si
points to i
again.
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).
Good practice is to never reference to the naked pointer after it has been assigned to a 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. 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). 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.
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!
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.