C++ shared_ptr Cycles: Parent/Child, Observer, Graph, Cache Patterns [#33-4]

C++ shared_ptr Cycles: Parent/Child, Observer, Graph, Cache Patterns [#33-4]

이 글의 핵심

Recognize shared_ptr cycles in trees, observers, graphs, and caches—then break them with weak_ptr and clear ownership.

Introduction: why shared_ptr cycles keep happening

Scenarios

  • Chat Room ↔ Session zombies.
  • DOM trees with parent/child shared_ptr edges.
  • Event bus retaining shared_ptr<Observer>.
  • Graph nodes with shared_ptr neighbors.

Essence: refcount never reaches 0 in a cycle—weak_ptr on the non-owning direction breaks it.

Topics: four patterns (parent/child, observer, graph, cache), complete examples, mistakes, best practices, diagnostics, performance.


Pattern 1: Parent/child tree

Wrong: shared_ptr parent in child and shared_ptr children in parent ⇒ cycle.
Right: vector<shared_ptr<Child>> + weak_ptr<Parent> (or the reverse, but one direction owns).

enable_shared_from_this to set weak_ptr parent when adding children.


Pattern 2: Observer

Subject should store weak_ptr<Observer>, not shared_ptr, unless it truly co-owns observers.


Pattern 3: Graph

Either weak_ptr back-edges, unique_ptr ownership with node indices, or central Graph owning storage.


Pattern 4: Cache

weak_ptr values let entries die when external **shared_ptr**s disappear; lock() misses reload assets.


Diagnostics

Leaks without obvious ASan? Draw ownership graph. Tools: heap profiling, Valgrind (cycle behavior differs), reasoning about strong counts.


Performance

weak_ptr storage is cheap; lock() costs like shared_ptr copy when upgrading.

Full runnable listings (tree, observer, graph snippets) follow the same structure as the main series posts.

Keywords

shared_ptr cycle, weak_ptr, observer, cache, memory leak