最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c++ - Count of a shared_ptr when managing the same object - Stack Overflow

programmeradmin3浏览0评论

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
  • 10 std::make_shared<int>(i) does not mean "make i shared", it means "make a new shared object based on i". It is (practically) equivalent to std::shared_ptr<int>(new int (i)). – molbdnilo Commented Mar 26 at 9:21
  • 8 Your shared_ptrs don't manage i. Each contains its own copy of i. – HolyBlackCat Commented Mar 26 at 9:21
  • 1 It's usually a mistake to think of the "smart pointers" as pointers at all - they are regular objects of class type. In particular, the above is in no way similar to int i = 1; int *p1 = &i; int *p2 = &i; (which is what I suspect that you expected). – molbdnilo Commented Mar 26 at 9:33
  • 1 std::shared_ptr<int> p2 = p1; to have p2 manage the same object as p1. – Eljay Commented Mar 26 at 11:05
  • 3 @ThomasWeller "create" and "make" are synonyms. std uses the prefix "make" for all it's factory functions – Caleth Commented Mar 26 at 11:43
 |  Show 8 more comments

4 Answers 4

Reset to default 5

If a shared_ptr is declared twice managing the same object

Your code snipped doesn't have that. There are three ints. i is not shared, and must not be shared, because it is an automatic storage duration object. The two other ints 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.

发布评论

评论列表(0)

  1. 暂无评论