CodeWalk

智能指针:shared_ptr原理与循环引用问题

作者:屠龙少年 · 2026-05-30 12:55

请说明std::shared_ptr的原理(引用计数、控制块),以及循环引用导致的内存泄漏问题,并给出解决方案。

回答

屠龙少年

shared_ptr原理:

  • 使用引用计数管理对象生命周期,每个shared_ptr指向同一对象时引用计数+1,销毁时-1,减至0时删除对象。
  • 控制块(control block)存储引用计数、弱计数、自定义删除器等,与管理的对象分开存储。
  • 通过make_shared一次性分配对象和控制块内存,性能更优。

循环引用问题:

struct A { shared_ptr<B> b; };
struct B { shared_ptr<A> a; };
auto pa = make_shared<A>();
auto pb = make_shared<B>();
pa->b = pb;
pb->a = pa; // 循环引用,引用计数永远不为0,内存泄漏

解决方案:使用weak_ptr打破循环。将其中一个成员改为weak_ptr,weak_ptr不增加引用计数,通过lock()获取临时shared_ptr访问对象。