Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ shared+ptr use_count for nullptr

I have 2 shared_ptrs 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)

like image 565
user2255299 Avatar asked Feb 20 '18 12:02

user2255299


People also ask

Can a shared ptr be Nullptr?

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 .

Can shared ptr be copied?

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.

What does Use_count return in C++?

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.

What is shared pointer in C++ example?

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.


2 Answers

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;
like image 86
Lightness Races in Orbit Avatar answered Sep 30 '22 14:09

Lightness Races in Orbit


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.

like image 42
Pavlo K Avatar answered Sep 30 '22 12:09

Pavlo K