zeropoint
zeropoint

Reputation: 245

shared_ptr and use_count

In the following code snippet:

shared_ptr<int> p;

{
    p = shared_ptr<int>(new int);
    cout<<p.use_count()<<endl;
}

cout<<p.use_count()<<endl;

The output comes out to be

1
1

I don't understand why the 1st output is 1 -- shouldn't it be 2?

Upvotes: 5

Views: 11636

Answers (3)

dans3itz
dans3itz

Reputation: 1615

 #include <memory>
 #include <iostream>

 int
 main(int argc, char** argv) {
   std::shared_ptr<int> p(new int);
   std::shared_ptr<int> p2(p);
   std::cout << p.use_count() << std::endl;
   return 0;
 }

output: 2

EXPLANATION/EDIT: In your source, the initial 'p' never held ownership of anything. In the 2nd reference to p, you are assigning to a temporary and basically giving up ownership to 'p'. Most likely, as well, the move constructor is used to satisfy this assignment.

EDIT: This was probably what you were going for?

 #include <memory>
 #include <iostream>

 int
 main(int argc, char** argv) {
   std::shared_ptr<int> p(new int);
   {
       std::shared_ptr<int> p2(p);
       std::cout << p.use_count() << std::endl;
   }
   std::cout << p.use_count() << std::endl;
   return 0;
 }

output: 2
        1

Upvotes: 7

bames53
bames53

Reputation: 88155

The temporary object's lifetime does not last long enough for the first p.use_count() to return 2. The temporary object is destroyed first, relinquishing its ownership on anything it owned.

Furthermore, since the temporary is an rvalue, the assignment to p will result in a move-assignment, which means the use-count will never be 2 anyway (assuming a quality implementation). Ownership is simply transferred from the temporary to p, never exceeding 1.

Upvotes: 10

huseyin tugrul buyukisik
huseyin tugrul buyukisik

Reputation: 11910

From boost.org:

template<class Y> explicit shared_ptr(Y * p); 
Requirements: p must be convertible to T *. Y must be a complete type. The     expression delete p must be well-formed, must not invoke undefined behavior, and     must not throw exceptions.

Effects: Constructs a shared_ptr that owns the pointer p.

Postconditions: use_count() == 1 && get() == p.

Throws: std::bad_alloc, or an implementation-defined exception when a resource other than memory could not be obtained.

Exception safety: If an exception is thrown, delete p is called.

Notes: p must be a pointer to an object that was allocated via a C++ new    expression or be 0. The postcondition that use count is 1 holds even if p is 0;    invoking delete on a pointer that has a value of 0 is harmless.

As you can see, it releases the last construct if you construct a new shared_ptr from the new int.

Upvotes: 1

Related Questions