C++中share_ptr中循环引用的问题
背景:
share_ptr已经很好用了,但是有一点share_ptr智能指针还是有内存泄露的情况,当两个对象相互使用一个shared_ptr成员变量指向对方,会造成循环引用,使引用计数失效,从而导致内存泄漏。
weak_ptr 是一种不控制对象生命周期的智能指针, 它指向一个 shared_ptr 管理的对象. 进行该对象的内存管理的是那个强引用的shared_ptr, weak_ptr只是提供了对管理对象的一个访问手段。weak_ptr 设计的目的是为配合 shared_ptr 而引入的一种智能指针来协助 shared_ptr 工作, 它只可以从一个 shared_ptr 或另一个 weak_ptr 对象构造, 它的构造和析构不会引起引用记数的增加或减少。weak_ptr是用来解决shared_ptr相互引用时的死锁问题,如果说两个shared_ptr相互引用,那么这两个指针的引用计数永远不可能下降为0,资源永远不会释放。它是对对象的一种弱引用,不会增加对象的引用计数,和shared_ptr之间可以相互转化,shared_ptr可以直接赋值给它,它可以通过调用lock函数来获得shared_ptr。
循环引用的例子:
#include <stdio.h> #include <iostream> #include <memory> class Child; class Parent; class Parent { private: std::shared_ptr<Child> ChildPtr = nullptr; //std::weak_ptr<Child> ChildPtr; public: Parent() { printf("Parent() +++++++++++++ \n"); } ~Parent() { printf("~Parent() +++++++++++++ \n"); } void SetChild(std::shared_ptr<Child> sp) { ChildPtr = sp; } }; class Child { private: std::shared_ptr<Parent> ParentPtr = nullptr; public: Child() { printf("Child() +++++++++++++ \n"); } ~Child() { printf("~Child() +++++++++++++ \n"); } void SetParent(std::shared_ptr<Parent> sp) { ParentPtr = sp; } }; void shareTest() { printf("shareTest +++++++++++++ \n"); { std::shared_ptr<Parent> p(new Parent); std::shared_ptr<Child> c(new Child); printf("构造完成 ... \n"); p->SetChild(c); c->SetParent(p); printf("p use count:%d\n", p.use_count()); printf("c use count:%d\n", c.use_count()); } printf("shareTest +++++++++++++ \n"); system("pause"); }
int main()
{
shareTest();
return 0;
}
运行结果:
可以看到在出了作用域后,p和c并没有被释放。
使用weak_ptr解决这个问题:
运行结果:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?