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:
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?
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.
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.
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.
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.
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
, or0
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.
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.
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