Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the maximum reference count in std::shared_ptr? What happens if you try to exceed it?

Tags:

If we assume that std::shared_ptr stores a reference count (which I realize the standard does not require, but I am unaware of any implementations that don't), that reference count has a limited number of bits, and that means there is a maximum number of references that are supported. That leads to two questions:

  • What is this maximum value?
  • What happens if you try to exceed it (e.g., by copying a std::shared_ptr that refers to an object with the maximum reference count)? Note that std::shared_ptr's copy constructor is declared noexcept.

Does the standard shed any light on either of these questions? How about common implementations, e.g., gcc, MSVC, Boost?

like image 267
KnowItAllWannabe Avatar asked Sep 13 '12 08:09

KnowItAllWannabe


People also ask

What happens when shared_ptr goes out of scope?

The smart pointer has an internal counter which is decreased each time that a std::shared_ptr , pointing to the same resource, goes out of scope – this technique is called reference counting. When the last shared pointer is destroyed, the counter goes to zero, and the memory is deallocated.

Is shared_ptr reference counting?

The shared reference counter counts the number of owners. Copying a std::shared_ptr increases the reference count by one. Destroying a std::shared_ptr decreases the reference count by one. If the reference count becomes zero, the resource will automatically be released.

How many bytes is a shared_ptr?

In a typical implementation, std::shared_ptr holds only two pointers. So 1000 shared pointers take up 1000 * 2 * sizeof(pointer) bytes of memory. Size of a pointer is 4 bytes on all 32-bit systems that follow ILP32 data model.

How can we maintain reference count of a pointer?

The smart pointer allocates a small block of memory to contain the reference counter. Each copy of the smart pointer then receives a pointer to the actual object and a pointer to the reference count.


2 Answers

We can get some information from the shared_ptr::use_count() function. §20.7.2.2.5 says:

long use_count() const noexcept; 

Returns: the number of shared_ptr objects, *this included, that share ownership with *this, or 0 when *this is empty.

[Note: use_count() is not necessarily efficient.—end note ]

At first sight the long return type seems to answer the first question. However the note seems to imply that shared_ptr is free to use any type of reference counting it wants to, including things like a list of references. If this were the case then theoretically there would be no maximum reference count (although there would certainly be a practical limit).

There is no other reference to limits on the number of references to the same object that I could find.

It's interesting to note that use_count is documented to both not throw and (obviously) to report the count correctly; unless the implementation does use a long member for the count I don't see how both of these can be theoretically guaranteed at all times.

like image 136
Jon Avatar answered Oct 13 '22 01:10

Jon


I'm not sure what the standard suggests, but look at it practically:

The reference count is most likely some sort of std::size_t variable. This variable can hold values up to -1+2^32 in 32-Bit environments and up to -1+2^64 in 64-Bit environments.

Now Image what would have to happen for this variable to reach this value: you would need 2^32 or 2^64 shared_ptr instances. That's a lot. In fact, that's so many that all memory would be exhausted long before you reach this number, since a one shared_ptr is about 8/16 bytes large.

Therefor, you are very unlikely to be able to reach the limit of the reference count if the size of the refcount variable is large enough.

like image 38
fat-lobyte Avatar answered Oct 13 '22 01:10

fat-lobyte