Search code examples
c++heap-memoryc++20dynamic-memory-allocationshared-ptr

C++ Primer 5th Ed - Stanley Lipmann: Question on shared_ptr.unique() used in conjunction with shared_ptr.reset()


First we have a shared_ptr defined as below:

shared_ptr<int> p(new int(42)); 

According to the text below:

The reset member is often used together with unique to control changes to the object shared among several shared_ptrs. Before changing the underlying object, we check whether we’re the only user. If not, we make a new copy before making the change:

if (!p.unique())
    p.reset(new int(*p)); // we aren't alone; allocate a new copy
*p += newVal; // now that we know we're the only pointer, okay to change this object

Question:
Shouldn't we only reset p when there's only 1 copy (p.use_count() == 1).
Here, if i read it correctly we're resetting p when p.use_count() != 1. Seems like opposite.

Thanks for any help.


Solution

  • The various shared_ptrs scattered throughout the program are all different instances of shared_ptr that, in this example, potentially point to the same object. If there is only one shared_ptr referring to the object O, we can change O with impunity. Otherwise we want to prevent other holders of shared_ptrs from being affected by the changes made to O by one holder.

    Trivial example: if there are more than one shared_ptr instances pointing to O,

    • P1 points to O
    • P2 points to O

    we copy O so that the changes the owner of P1 wishes to make are not seen by the owner of P2. We will wind up with

    • P1 points to Copy
    • P2 points to O

    Now that P1 is the only pointer referencing Copy, P1's holder can make changes without affecting P2. And since P2 is the only pointer to O, it can make changes without copying Oin the future, unless P2 is copied into P3 and we once again have multiple "owners" of O.

    You sometimes see behaviour like this with string implementations. When you copy this kind of string, both strings save storage and time by sharing the source string's data. But if either string needs to change that data, it pays for a new copy so that it is the only one changed.