I have 2 shared_ptr
s defined and assigned nullptr
. In case 1, I'm using default constructor and in case 2, I used constructor with delete method.
shared_ptr<int> sptr2(nullptr);
cout << "sptr2 use_count: " << sptr2.use_count() << endl;
shared_ptr<int> sptr6(nullptr, default_delete<int>());
cout << "sptr6 use_count: " << sptr6.use_count() << endl;
The output is:
sptr2 use_count: 0
sptr6 use_count: 1
I cannot understand why sptr6 has use count of 1 when it does not have any valid pointer.
g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-16)
A null shared_ptr does serve the same purpose as a raw null pointer. It might indicate the non-availability of data. However, for the most part, there is no reason for a null shared_ptr to possess a control block or a managed nullptr .
The ownership of an object can only be shared with another shared_ptr by copy constructing or copy assigning its value to another shared_ptr . Constructing a new shared_ptr using the raw underlying pointer owned by another shared_ptr leads to undefined behavior.
std::shared_ptr<T>::use_count Returns the number of different shared_ptr instances (this included) managing the current object. If there is no managed object, 0 is returned.
The shared_ptr type is a smart pointer in the C++ standard library that is designed for scenarios in which more than one owner might have to manage the lifetime of the object in memory.
Per [util.smartptr.shared.const]
in C++11 & C++14 (I haven't checked C++17), the shared_ptr
is "empty" if you pass no argument. Otherwise, the shared_ptr
"owns p
" even for the case that p
is a nullptr_t
.
When a deleter is provided this makes sense (you have to store the deleter somewhere, after all), but what the purpose of this is for the single-argument constructor I couldn't say.
I'm apparently not alone, because the C++11/C++14 specification for the actual functions ([util.smartptr.shared]/1
) lists constexpr shared_ptr(nullptr_t) : shared_ptr() { }
, which suggests this construction (but not the construction that provides a deleter) should result in an "empty" shared_ptr
!
But this is in direct contradiction to the listed semantics (which specifically give use_count == 1
as a post-condition for both of your examples), and would therefore appear to be a bug in the standard.
GCC has apparently chosen to side with the function specification (as has cppreference.com). At least your deleter should be a no-op in this case.
To actually use the default constructor, write this:
shared_ptr<int> sptr;
The reason of different behavior caused by the shared_ptr design. SharedPtr refer to "control object", and control object refers to "user object".
If you initialize shared_ptr with nullptr (sptr2), control object is not created. Constructor does nothing.
If you initialize shared_ptr with deleter (sptr6), control object is created to store deleter. So, if control object created, it has to have reference count 1.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With