Reputation: 103
I want to understand how the reference count of the managed object in a shared_ptr
is affected when a shared_ptr
is assigned to another.
I came across the following statement in C++ primer, 5th edition, that:
For example, the counter associated with a shared_ptr is incremented when ... we use it as the right-hand operand of an assignment... The counter is decremented when we assign a new value to the shared_ptr...
As an example its shown there:
auto p = make_shared<int>(42); // object to which p points has one user
auto q(p); // p and q point to the same object
// object to which p and q point has two users
auto r = make_shared<int>(42); // int to which r points has one user
r = q; // assign to r, making it point to a different address
// increase the use count for the object to which q points
// reduce the use count of the object to which r had pointed
// the object r had pointed to has no users; that object is automatically freed
When I run a similar code, the above is not my observation:
Code:
#include<iostream>
#include<memory>
int main()
{
std::shared_ptr<int> sh1 = std::make_shared<int>(1);
std::shared_ptr<int> sh2 = std::make_shared<int>(2);
sh2 = sh1;
std::cout << "sh1 use count: " << sh1.use_count() << std::endl;
std::cout << "sh2 use count: " << sh2.use_count() << std::endl;
return 0;
}
Output:
sh1 use count: 2
sh2 use count: 2
How can the use_count
of sh2
also 2? Should not it be 0 as per the mentioned text above? Am I missing something here?
Upvotes: 5
Views: 10565
Reputation: 10391
Originally we have
sh1.use_count =1 and
sh2.use_count = 1
*sh1 = 1 and
*sh2 = 2
After sh2 = sh1
. Both sh1 ->int(1) <- sh2
.
What happen to int(2)
?
It got destroyed as the sh2
now points to int(1)
.
Hence, we have
sh1.use_count == sh2.use_count
*sh1 == *sh2
*sh1 and *sh2 have 1
Upvotes: 0
Reputation: 26356
At first you had sh1.use_count=1
and sh2.use_count=1
. Now when you assign using sh2=sh1
, this is what happens:
sh2
counter is decreased by one, because sh2
(the shared_ptr
) is going to take another pointersh2.use_count=0
now, the object under its pointer, which is int(2)
is destroyed.sh2
to a new object, which belongs to sh1
, and hence its counter is increased by one, so: sh2.use_count=2
, and of course also sh1.use_count=2
, because both shared_ptr
objects point to the same object, which is the int(1)
.Upvotes: 15
Reputation: 37599
I think this misunderstanding occurs because you think that counter is stored in shared_ptr
instance along with a pointer to an owned object. However in reality an instance of shared_ptr
contains only a pointer to an internal storage object that contains both reference counter and a pointer to an owned object. Therefore when you perform sh2 = sh1;
assignment you make sh2
refer to the same internal storage object as sh1
so the counters value reported by both sh1
and sh2
is taken from the same source.
Upvotes: 4