How do shared pointers work?

前端 未结 5 1817
无人共我
无人共我 2020-12-02 13:34

How do shared pointers know how many pointers point to that object? (shared_ptr, in this case)

5条回答
  •  無奈伤痛
    2020-12-02 13:40

    There are at least three well-known mechanisms.

    External Counters

    When the first shared pointer to an object is created, a separate reference count object is created and initialized to 1. When the pointer is copied, the reference count is increased; when a pointer is destroyed it is decreased. Pointer assignment increases one count and decreases another (in that order, or else self-assignment ptr=ptr will break). If the reference count hits zero, no more pointers exist and the object is deleted.

    Internal counters

    An internal counter requires that the object pointed to has a counter field. This is usually achieved by deriving from a specific base class. In exchange, this saves a heap allocation of the reference count, and it allows repeated creation of shared pointers from raw pointers (with external counters, you'd end up with two counts for one object)

    Circular links

    Instead of using a counter, you can keep all shared pointers to an object in a circular graph. The first pointer created points to itself. When you copy a pointer, you insert the copy in the circle. When you delete it, you remove it from the circle. But when the destroyed pointer pointed to itself, i.e. when it's the only pointer, you delete the pointed-to object.

    The downside is that removing a node from a circular single-linked list is rather expensive as you have to iterate over all nodes to find the predecessor. This can be especially painful due to poor locality of reference.

    Variations

    The 2nd and 3rd idea can be combined: the base class can be part of that circular graph, instead of containing a count. Of course, this means that the object can be deleted only when it points to itself (cycle length 1, no remaining pointers to it). Again, the advantage is that you can create smart pointers from weak pointers, but the poor performance of deleting a pointer from the chain remains an issue.

    The exact graph structure for idea 3 doesn't matter too much. You could also create a binary tree structure, with the pointed-to object at the root. Again, the hard operation is removing a shared pointer node from that graph. The benefit is that if you have many pointers on many threads, growing part of the graph is not a highly contended operation.

提交回复
热议问题