If a shared_ptr
is declared twice managing the same object, why does the count not increase to two, since the same object is being managed?
int i = 1;
std::shared_ptr<int> p1 = std::make_shared<int>(i);
std::shared_ptr<int> p2 = std::make_shared<int>(i);
std::cout << p1.use_count() << std::endl;
In the obove the the count is 1, not 2.
If a shared_ptr
is declared twice managing the same object, why does the count not increase to two, since the same object is being managed?
int i = 1;
std::shared_ptr<int> p1 = std::make_shared<int>(i);
std::shared_ptr<int> p2 = std::make_shared<int>(i);
std::cout << p1.use_count() << std::endl;
In the obove the the count is 1, not 2.
Share Improve this question edited Mar 26 at 13:12 wohlstad 29.9k16 gold badges61 silver badges93 bronze badges asked Mar 26 at 9:18 random_acctrandom_acct 232 bronze badges 13 | Show 8 more comments4 Answers
Reset to default 5If a shared_ptr is declared twice managing the same object
Your code snipped doesn't have that. There are three int
s. i
is not shared, and must not be shared, because it is an automatic storage duration object. The two other int
s are managed by p1
and p2
respectively, and the value they hold was copied from i
.
You create 2 different pointers, the make_shared()
function creates a new pointer, not copies it. To make the p2 pointer refer to the p1 pointer, you must use the copy constructor, and shared_ptr
must refer to a pointer in which case a new int is created instead of i
:
std::shared_ptr<int> p1 = std::make_shared<int>(i);
std::shared_ptr<int> p2 = p1; // copy and increment the counter
//p1.use_count(); == 2
in order to refer to the original i
you have to:
int* i = new int (1);
std::shared_ptr<int> p1(i); // means to refer to an existing pointer
std::shared_ptr<int> p2 = p1;
//p1.use_count(); == 2
If you look at the cppreference documentation for std::make_shared()
, it clearly states:
Allocates memory for an object and initialize the object with the supplied arguments. Returns a std::shared_ptr object managing the newly created object.
Making a long story short: your code is creating two separate pointers.
A better way should be:
int i = 1;
std::shared_ptr<int> p1 = std::make_shared<int>(i);
std::shared_ptr<int> p2 = p1;
std::cout << p1.use_count() << std::endl;
This should give you the correct result.
However, if you meant that p1
and p2
should be separate pointers and you wonder why std::make_shared<int>(i)
is not increasing the count, it is because make_shared()
is creating a temporary std::shared_ptr<int>
instance which is destroyed right after it is set on p1
or p2
.
An interesting feature of formal logic is that you can prove anything given a false premise. (Maybe not so interesting for the many out there who confuse themselves by assuming that a false premise is true, rather than testing it.)
If a
shared_ptr
is declared twice managing the same object
Let's put this premise to the test. Before checking the use count, let's try to demonstrate that your shared pointers are managing the same object. A straight-forward way to do this is to modify one object and see the change in the other object.
#include <iostream>
#include <memory>
int main() {
int i = 1;
std::shared_ptr<int> p1 = std::make_shared<int>(i);
std::shared_ptr<int> p2 = std::make_shared<int>(i);
i = 0;
*p2 = 2;
std::cout << " i: " << i << "\n*p1: " << *p1 << "\n*p2: " << *p2 << "\n";
}
Output:
i: 0
*p1: 1
*p2: 2
Three different values? Apparently, there are three distinct objects in play.
Each invocation of make_shared
makes a shared_ptr
and also makes an object to which the pointer points. Calling make_shared<int>
twice creates two int
objects. Add in the original, i
, and you get three objects.
std::make_shared<int>(i)
does not mean "makei
shared", it means "make a new shared object based oni
". It is (practically) equivalent tostd::shared_ptr<int>(new int (i))
. – molbdnilo Commented Mar 26 at 9:21shared_ptr
s don't managei
. Each contains its own copy ofi
. – HolyBlackCat Commented Mar 26 at 9:21int i = 1; int *p1 = &i; int *p2 = &i;
(which is what I suspect that you expected). – molbdnilo Commented Mar 26 at 9:33std::shared_ptr<int> p2 = p1;
to have p2 manage the same object as p1. – Eljay Commented Mar 26 at 11:05std
uses the prefix "make" for all it's factory functions – Caleth Commented Mar 26 at 11:43