C++中share_ptr中循环引用的问题

news/2024/12/26 16:30:07/文章来源:https://www.cnblogs.com/xcywt/p/18420199

背景:

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解决这个问题:

 运行结果:

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/799756.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

易优eyoucms网站怎么关闭后台登录验证码呢

在易优CMS (EyouCMS) 中关闭后台登录验证码的操作相对简单。以下是详细的步骤: 1. 登录后台 首先需要登录到后台管理系统。 登录后台访问后台登录页面:访问/admin.php或相应的后台登录地址。输入用户名和密码:输入管理员账号和密码登录后台。2. 进入系统设置 进入后台后,找…

易优eyoucms网站后台登录验证码是否不用,也可以登录?

在易优CMS (EyouCMS) 中,后台登录验证码是否必须取决于您的配置。如果您不需要验证码,可以通过以下几种方法来关闭它,从而实现无需验证码即可登录后台。 方法一:通过后台设置关闭登录后台:访问后台登录页面,并登录。进入系统设置:在后台左侧菜单栏中找到“系统设置”或“…

易优eyoucms网站后台登录页面错位/乱码,CSS文件丢失

当易优CMS后台登录页面出现错位或乱码,通常是由于CSS文件丢失或加载不正确导致的。以下是详细的解决步骤: 1. 备份现有文件 在进行任何操作之前,先备份现有文件,以防万一。 备份现有文件登录FTP客户端:使用FTP客户端登录到服务器。备份现有文件:备份整个网站目录,或者至…

正也科技-辖区与指标管理系统 强化决策支持

正也科技的“辖区与指标管理系统”设计理念先进,旨在通过科学合理的组织架构和精细化的指标管理,帮助企业实现更高效的市场布局、人员配置及业绩监控。以下是对该系统核心功能的进一步阐述及其对企业运营带来的优势:正也科技辖区管理组织架构维护 灵活性与适应性:系统允许企…

Linux awk中输出上下两列值之间的差值

001、[sy20213040737@admin2 test]$ cat a.txt ## 测试数据 3 8 34 50 [sy20213040737@admin2 test]$ awk {if(NR == 1){tmp = $1} else {print $1 - tmp; tmp = $1}} a.txt ## 输出差值 5 26 16 。

对象字符串转换为数组对象

数据源格式:{\n "填写说明": "每个学期的开学之前,需要调整这里面的配置,这样课表和一卡通对接的才能是正确的数据",\n "学年编号": "2024-2025",\n "学期编号": "1"\n}"{"填写说明":…

2414.最长的字母序连续字符串的长度

字母序连续字符串 是由字母表中连续字母组成的字符串。换句话说,字符串 "abcdefghijklmnopqrstuvwxyz" 的任意子字符串都是 字母序连续字符串 。 例如,"abc" 是一个字母序连续字符串,而 "acb" 和 "za" 不是。 给你一个仅由小写英文…

易优eyoucms网站后台登录一直显示验证码错误

当后台登录一直显示验证码错误时,可以尝试以下几个方面进行排查和解决: 1. 检查目录权限和所有者 确保目录权限和所有者设置正确,这对于文件的读写非常重要。 修改目录权限修改目录权限:将目录权限设置为755,文件权限设置为644。 使用命令chmod -R 755 /path/to/directory…

易优cms网站验证码不显示是什么情况

当您在使用易优CMS时遇到验证码不显示的问题,可能的原因有很多。以下是一些可能的情况及解决办法: 可能的情况及解决办法 1. CMS版本太低下载修复包:访问易优CMS的官方网站或修复包下载页面(如易优CMS日志),下载最新的修复包。 解压缩修复包,并将其中的文件上传覆盖到网…

Flink-cdc丢失数据排查

一、获取任务信息 任务id:i01f51582-d8be-4262-aefa-000000 任务名称:ods_test1234 丢失的数据时间:2024-09-16 09:28:47二、数据同步查看日志 1、筛选日志 筛选2024-09-16 09:28:47 到 5分钟后数据 2、查找快照id,筛选内容Committed snapshot 7258609197164498019 (BaseRo…

纷享销客“子流程”创新——企业流程管理的革新之选

Jack是一家电子商务企业的销售经理,近期他的公司订单量激增,但随之而来的退货流程却成了一个棘手的问题。每天,成百上千的退货请求涌向客服部门,而退货流程的每一步:从接收退货申请、物流派单、商品检验入库,到最终的财务退款,都至关重要,却也复杂繁琐。任何一步的延误…

易优cms网站错误提示{msg:u5199u5165u8868ey_ad_positionu8bb0u5f55u5931u8d25uff0cu8bf7u5c1du8bd5F5u5237u65b0!}

根据错误提示和处理步骤,我们可以按部就班地解决这个问题。以下是详细的步骤说明: 1. 准备SQL文件 首先,需要准备一个包含两条更新语句的SQL文件。 步骤一:创建SQL文件打开文本编辑器(如Notepad++、VSCode等)。将以下两条SQL语句复制并粘贴到文本编辑器中:UPDATE `ey_ad…