Reputation: 245
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
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
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
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