在以前的文章中,我们讲过C++的shared_ptr,利用它可以实现基于引用计数的指针回收,从而防止出现内存泄露。

但是事实上,即使是采用了shared_ptr,在存在循环引用的情况下其实仍然有可能会导致内存泄露,举个例子:

struct B;

struct A
{
std::shared_ptr<B> p;
}; struct B
{
std::shared_ptr<A> p;
}; int main()
{
{
auto a = std::make_shared<A>();
auto b = std::make_shared<B>();
a->p = b;
b->p = a;
}
return 0;
}

A和B之间相互引用,在大括号中,它们的引用计数为2;即使是被销毁后,引用计数也只是变成了1,不会销毁,这样就出现了内存泄漏。

为了解决这种循环引用的问题,就需要一种特殊的智能指针:weak_ptr。这种智能指针在指向对象时,对象的引用计数不会+1,所以可以这么实现:

#include <memory>

struct B;

struct A
{
std::weak_ptr<B> p;
}; struct B
{
std::weak_ptr<A> p;
}; int main()
{
{
auto a = std::make_shared<A>();
auto b = std::make_shared<B>();
a->p = b;
b->p = a;
}
return 0;
}

以上的代码,在大括号内,a和b的引用计数不会因为被weak_ptr指向而增加,因此它们的引用计数始终为1;这样当大括号结束的时候,它们就能被顺利销毁了。我们可以加一个变量查看一下大括号结束时的引用计数:

int main()
{
std::weak_ptr<A> p;
{
auto a = std::make_shared<A>();
auto b = std::make_shared<B>();
a->p = b;
b->p = a;
p = a;
}
std::cout << p.use_count() << std::endl;
return 0;
}

最终的运行结果为0,也就是此时a指向的对象已经被销毁了,不再存在内存泄漏。

C++的weak_ptr的更多相关文章

  1. 智能指针weak_ptr解决循环依赖问题

    #include <iostream> #include <memory> class Woman; class Man{ private: std::weak_ptr< ...

  2. [6] 智能指针boost::weak_ptr

    [1]boost::weak_ptr简介 boost::weak_ptr属于boost库,定义在namespace boost中,包含头文件 #include<boost/weak_ptr.hp ...

  3. C++ Primer : 第十二章 : 动态内存之unique_ptr和weak_ptr

    unique_ptr 一个unique_ptr拥有它所管理的对象,与shared_ptr不同,unique_ptr指向的对象只能有一个用户.当unique_ptr被销毁后,它所指向的对象也被销毁. 定 ...

  4. weak_ptr的一点认识

    近期在补充和梳理C++方面的知识的时候,遇到了WeakPtr这个概念和用法,不甚明白,Google出了一堆文字,包括Boost的shared_ptr和weak_ptr的比较,以及其他一些博客里面给的例 ...

  5. 【STL学习】智能指针之weak_ptr

    简介 weak_ptr是shared_ptr的观察者,它不会干扰shared_ptr所共享对象的所有权,当一个weak_ptr所观察的shared_ptr要释放它的资源时,它会把相关的weak_ptr ...

  6. shared_ptr与weak_ptr的例子

    12.20 编写程序,逐行读入一个输入文件,将内容存入一个StrBlob中,用一个StrBlobPtr打印出StrBlob的每个元素. StrBlob.h #ifndef STRBLOB_H #def ...

  7. [转] weak_ptr解决shared_ptr环状引用所引起的内存泄漏

    http://blog.csdn.net/liuzhi1218/article/details/6993135 循环引用: 引用计数是一种便利的内存管理机制,但它有一个很大的缺点,那就是不能管理循环引 ...

  8. #include <boost/weak_ptr.hpp>

    弱指针boost::weak_ptr的定义在boost/weak_ptr.hpp里.到目前为止介绍的各种智能指针都能在不同的场合下独立使用.相反,弱指针只有在配合共享指针一起使用时才有意义.因此弱指针 ...

  9. C++智能指针--weak_ptr

    weak_ptr是对对象的一种弱引用,它不会添加对象的引用计数.weak_ptr和shared_ptr之间能够相互转换.shared_ptr能够直接赋值给week_ptr,week_ptr可通过调用l ...

  10. stl中auto_ptr,unique_ptr,shared_ptr,weak_ptr四种智能指针使用总结

    stl中auto_ptr,unique_ptr,shared_ptr,weak_ptr四种智能指针使用总结 1. auto_ptrauto_ptr主要是用来解决资源自动释放的问题,比如如下代码:voi ...

随机推荐

  1. 苹果手机备份及itunes下载更新路径

    1.itunes备份路径: C:\Users\xxx.xxx\AppData\Roaming\Apple Computer\MobileSync\Backup\ 2.itunes更新IOS路径: C: ...

  2. mac 查看本机ip

    创建 ip.sh 文件,文件内容为 ifconfig -a | grep -e "inet[^6]" |\ sed -e "s/.*inet[^6][^0-9]*\([0 ...

  3. Office & WPS 基础篇

    基础知识 安装office 推荐使用Microsoft Office,原因不详,不做讨论 使用Office tool plus安装,不要三年前版本,一般三年一代,工具自己找,版本文件自己找. 具体选项 ...

  4. Day 22 22.2:scrapy部署

    scrapy项目部署 scrapyd部署工具介绍 scrapyd是一个用于部署和运行scrapy爬虫的程序,它由 scrapy 官方提供的.它允许你通过JSON API来部署爬虫项目和控制爬虫运行. ...

  5. Cupboard and Balloons CodeForces - 342C

    Cupboard and Balloons CodeForces - 342C 找到不变的点 抓住不确定的点进行讨论 #include<iostream> #include<cmat ...

  6. Linux环境使用Docker安装MySql

    系统环境: CentOS 7.6 64位(同样适用于Ubuntu) 安装步骤: 1.创建文件夹 /home/docker/mysql/config /home/docker/mysql/data 2. ...

  7. git拉取本地或者分支

    拉取本地 git clone 拉取的仓库地址 新建一个文件夹,然后右键 拉取分支到本地 也是新建一个文件夹右键点击 Git Bash Here 然后输入 git clone -b 分支名称 分支地址 ...

  8. react 学习笔记更新2.0

    1.性能优化 1.shouldComponentUpdate 在render调用之前会调用shouldComponentUpdate,不建议在 shouldComponentUpdate() 中进行深 ...

  9. HTTP相关知识学习

    五层网络模型 应用层 包括HTTP,FTP... HTTP支持客户/服务器模式 简单快速有getpost方法 灵活,可以传输任意类型 无连接,每次连接只处理一个请求,收到应答就关闭 无状态,对于事物处 ...

  10. springboot java redis 监听超时事件

    package ideal4j.pfa.config.redis; import cn.hutool.core.date.DateTime; import com.alibaba.fastjson.J ...