在以前的文章中,我们讲过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. RSA 非对称加密

    原文链接:https://www.jianshu.com/p/d56a72013392 RSA 是一种非对称加密算法,在实际业务中经常使用此算法对数据进行加密.但是它的加解密速度较慢,不太适用于高并发 ...

  2. C++11 mutex unique_lock condition_variable 互斥锁 条件变量

    创建项目再进行测试比较麻烦,可以使用这个在线编译器进行验证,快速方便 C++11在线编译器 mutex是互斥锁,互斥量 condition_variable是条件变量 std::mutex m; vo ...

  3. rust字节数组转换为string

    一.String::from_utf8 fn main() { let bytes = vec![0x41, 0x42, 0x43]; let s = String::from_utf8(bytes) ...

  4. Java方法之方法的重载

    方法的重载 重载就是在一个类中,有相同的函数名称,但形参不同的函数. 方法的重载的规则: 1.方法名称必须相同. 2.参数列表必须不同(个数不同.或类型不同.参数排列顺序不同等). 3.方法的返回类型 ...

  5. Jquery_002

    6.$.ajax方法 $.ajax([options]) options是一个json格式的对象,参数是通过键值对的形式存在的 常用的参数如下: async:(默认: true) 默认设置下,所有请求 ...

  6. tzoj:3613 突破包围

    http://www.tzcoder.cn/acmhome/problemdetail.do?&method=showdetail&id=3613 算出两两之间min距离,然后从起点开 ...

  7. springsecurity 配置swagger

    最近在学习springsecurity 安全框架,具体是什么概念在这里不一一赘述了.下面呢,咱们一起搭建一下简单的springsecurity swagger 项目感受一下. 首先初始化spring ...

  8. <二>JMeter/Navicat for MYSQL运行案例

    一.JMeter 1. 下载地址:http://jmeter.apache.org/download_jmeter.cgi 2. 选择适合的版本进行下载,如下: 3. 将下载好的压缩包解压到任意文件夹 ...

  9. Vue3 流程图组件库 Vue Flow 简单使用

    官网 Vue Flow 官网 Vue Flow GitHub 安装 npm i --save @vue-flow/core yarn add @vue-flow/core pnpm i @vue-fl ...

  10. VirtualBox_Ubuntu22.10_Terminal无法打开

    https://blog.csdn.net/weixin_43959807/article/details/128872860