Search code examples
c++shared-ptr

swap the content of 2 shared_ptr


When swapping the content of two shared_ptrs, only the contents are swapped. When there is a shared_ptr created from the other one before the swap, I am surprised that the content of the new shared_ptr copy remains the same.

Here is an example:

std::shared_ptr<int> foo (new int(10));
std::shared_ptr<int> bar (new int(20));

auto abc = foo;
std::swap (foo, bar);
std::cout << "foo: " << *foo << '\n';
std::cout << "bar: " << *bar << '\n';
std::cout << "abc: " << *abc << '\n';

It prints:

foo: 20
bar: 10
abc: 10

Why is abc not 20 in this case? Given that it's a copy of foo.


Solution

  • shared_ptr is just a pointer to data. You are not swapping the data itself, you are swapping the pointers.

    Lets look at it step-by-step:

    std::shared_ptr<int> foo (new int(10));
    std::shared_ptr<int> bar (new int(20));
    

    After these statements, you have two pointers to two separate allocated ints:

    [ foo ] ---> [10]
    [ bar ] ---> [20]
    
    auto abc = foo;
    

    This statement then creates abc to point at the same allocated int that foo is pointing at. So, before the swap, you now have:

    [ foo ] -+-> [10]
             |
    [ abc ] -+
    
    [ bar ] ---> [20]
    
    std::swap (foo, bar);
    

    Then, you are swapping the pointers that foo and bar are holding, but you are leaving the pointer in abc alone. So, after the swap, you now have:

        +---------------+
        |               |
    [ foo ]  +-> [10]   |
             |          |
    [ abc ] -+          |
             |          |
    [ bar ] -+   [20] <-+
    

    That is why *foo prints 20, *bar prints 10, and *abc prints 10.