引子

  c++中动态内存的管理是通过new和delete来完成的,只要保证new和delete的配对使用,是没有问题的。但是有时候我们会忘记释放内存,甚至有时候我们根本就不知道什么时候释放内存。特别时在多个线程间共享数据时,更难判断内存该何使释放。这种情况下就机器容易产生引用非法内存的指针。                                                                                                    

  为了更容易(同时也更安全的管)的使用动态内存,新的标准库(C++11)提供了两种智能指针(smart pointer)类型来管理动态对象。智能指针的行为类似于常规指针。重要的区别是它负责自动释放所指向的对象。新标准提供的这两种智能指针的区别在于管理底层指针的方式:shared_ptr允许多个指针指向同一个对象;unique_ptr则独占所指向的对象。标准库还定义了一个weak_ptr的伴随类,他是一种弱引用,指向shared_ptr所管理的对象。这三种类型都定义在memory头文件中。

初始化 sahred_ptr

  智能指针的使用方式与普通指针类似。解引用一个智能指针返回它指向的对象。如果在一个条件判断中使用智能指针,效果就是检测它是否为空:

#include <iostream>using namespace std;int main()
{  /*---------空指针------------*/shared_ptr<string> p1;if(!p1)                         //!默认初始化的智能指针中保存着一个空指针!并不是""空字符串cout<<"p1==NULL"<<endl;/*---------初始化------------*/shared_ptr<string> p2(new string); if(p2&&p2->empty()){         //!需要注意的时empty时属于string的成员函数。 *p2="helloworld"; cout<<*p2<<endl;}
//    shared_ptr<int> pa = new int(1);//!error:不允许以暴露裸漏的指针进行赋值操作。//一般的初始化方式shared_ptr<string> pint(new string("normal usage!"));cout<<*pint<<endl;//推荐的安全的初始化方式shared_ptr<string> pint1 = make_shared<string>("safe uage!");cout<<*pint1<<endl;
}

关于get()函数;

智能指针定义了一个名为get的函数,它返回一个内置指针,指向智能指针的管理的对象。此函数设置的初衷是当我们向不能使用智能指针的代码传递一个内置指针。使用get返回指针的代码不能delete此指针。

#include <iostream>
#include <memory>
using namespace std;void useShared_ptr(int *p)
{cout<<*p<<endl;
}void delePointer(int *p)
{delete p;
}int main(int argc, char *argv[])
{shared_ptr<int> p1 = make_shared<int>(32);
//    shared_ptr<int>p2(p1.get());  //!错误的用法:但是p1、p2各自保留了对一段内存的引用计数,其中有一个引用计数耗尽,资源也就释放了。useShared_ptr(p1.get());
//    delePointer(p1.get());        //!error:return 0;
}

再次声明:get用来将指针的访问权限传递给代码,只有在确定代码不会delete指针的情况下,才能使用get。特别是,永远不要用get初始化另一个智能指针或者为另一个智能指针赋值!

 关于mak_shared函数:

  最安全的分配和使用动态内存的方法是调用一个名为make_shared的标准库函数,此函数在动态内存中分配一个对象并初始化它,返回此对象的shared_ptr。与只能指针一样,make_shared也定义在头文件memory中。

#include <iostream>
using namespace std;int main()
{shared_ptr<int> p3 = make_shared<int>(42);cout<<*p3<<endl;shared_ptr<string> pstr = make_shared<string>("99999");cout<<*pstr<<endl;shared_ptr<int> pint = make_shared<int>(); //!默认初始化为 0cout<<*pint<<endl;auto pau = make_shared<string>("auto");    //!更简单,更常用的方式。cout<<*pau<<endl;
}

shared_ptr的拷贝和赋值

  当进行拷贝或者赋值操作时,每个shared_ptr都会记录有多少个其他的shared_ptr指向相同的对象:

#include <iostream>
using namespace std;int main()
{auto p = make_shared<int>(42); //!p指向的对象只有p一个引用者。cout<<p.use_count()<<endl;auto q(p);                     //!p和q指向相同的对象,此对象有两个引用者。cout<<p.use_count()<<endl;return 0;
}

函数传参 

  • by const reference: void foo(const shared_ptr<T>& p)

  • or by value: void foo(shared_ptr<T> p) ?

void foo(const std::shared_ptr<int>& p)
{static int x = 0;*p = ++x;
}int main()
{auto p = std::make_shared<int>();auto start = clock();for (int i = 0; i < 10000000; ++i){foo(p);}    std::cout << "Took " << clock() - start << " ms" << std::endl;
}

Using VS2015, x86 release build, on my intel core 2 quad (2.4GHz) processor

const shared_ptr&     - 10ms
shared_ptr            - 281ms 

转载自https://www.cnblogs.com/wangkeqin/p/9351191.html

C++内存管理之shared_ptr相关推荐

  1. 【Boost】系列03:内存管理之shared_ptr智能指针

    最有价值的!最有用的引用计数型智能指针,可以被拷贝和赋值,可以作为STL容器的元素: 1,基本用法: #include <boost/smart_ptr.hpp> #include < ...

  2. 《C++应用程序性能优化::第五章动态内存管理》学习和理解

    <C++应用程序性能优化::第五章动态内存管理>学习和理解 说明:<C++应用程序性能优化> 作者:冯宏华等 2007年版. 2010.8.29 cs_wuyg@126.com ...

  3. C++内存管理全景指南

    导语 深入理解C++内存管理,一文了解所有C++内存问题,万字长文,建议收藏 随着人工智能,云计算等技术的迅猛发展,让Python,go等新兴语言流行了起来,很多人以为C++可能已经过时了,确实,C+ ...

  4. 深入理解C++内存管理

    深入理解C++内存管理 一文了解所有C++内存的问题 AlexCool 目录 一  C++内存模型 二  C++对象内存模型 三 C++程序运行内存空间模型 四  C++栈内存空间模型 五 C++堆内 ...

  5. Linux内存管理初探

    linux内存是后台开发人员,需要深入了解的计算机资源.合理的使用内存,有助于提升机器的性能和稳定性.本文主要介绍linux内存组织结构和页面布局,内存碎片产生原因和优化算法,linux内核几种内存管 ...

  6. linux内存管理总结

    内存管理可以分为三个层次,自底向上分别是: 操作系统内核的内存管理 用户空间lib库的内存管理算法 应用程序从lib库申请内存后,根据应用程序本身的程序特性进行优化, 比如使用引用计数std::sha ...

  7. java 内存管理 知乎_[知乎]Java 语言的 GC 为什么不实时释放内存?

    下面是RednaxelaFX的回答: 1.最基本的纯引用计数方式的自动内存管理可以做到实时释放死对象,但却无法处理存在循环引用的对象图的释放. 这个问题一定程度上可以通过引入弱引用的概念来解决,但通用 ...

  8. C++大法:举世闻名之BOOST大法精华浅析(三)内存管理库(小白piao分享)

    文章目录 三.内存管理库 3.1 smart_ptr 3.1.1 RAII机制 3.1.2 智能指针 3.1.3 scoped_ptr 3.1.4 scoped_array 3.1.5 shared_ ...

  9. 拒绝内存泄露,谈一些纯代码iPhone开发中的内存管理

    笔者刚从学校出来,算上实习期,接触iPhone开发已有半载,也算是对iPhone(iOS)开发中的内存管理有了些认识,由于开发中一直没有用Interface Builder,本文就谈谈纯代码iPhon ...

  10. 几种常用内存管理底层介绍

    需求 系统的物理内存是有限的,而对内存的需求是变化的, 程序的动态性越强,内存管理就越重要,选择合适的内存管理算法会带来明显的性能提升. 比如nginx, 它在每个连接accept后会malloc一块 ...

最新文章

  1. 障碍期权定价 python_[宜配屋]听图阁
  2. MySQL—事务及其特征
  3. 巨头间未来战争-丰收节交易会·万祥军:农业AI发展概况
  4. php记录邮件发送,有关php邮件发送一点记录
  5. NAND FLASH 和NOR FLASH工作原理
  6. list和tuple
  7. 内联脚本被视为是有害的_数据类被认为有害
  8. 2019阿里云618大促主会场全攻略
  9. 蜕变成蝶~Linux设备驱动之字符设备驱动
  10. python中集合运算_入门 | 一文带你了解Python集合与基本的集合运算
  11. 判断QButtonGroup中哪个QRadioButton被选中
  12. UVALive3713_Astronauts
  13. OpenNebula概述
  14. 23计算机考研人第一周反思总结
  15. 股票学习(技术指标--个股贡献度)
  16. java课程心得_Java课程的感想
  17. 差影-Variation Model
  18. 阿里云建站保证百度收录3000+网站模板
  19. 男子学比基尼电影派对开泡澡电影院 泡澡电影被赞好创意!
  20. Transformer课程 第7课Gavin大咖 BERT文本分类-BERT Fine-Tuning

热门文章

  1. 前端开发必须知道的JS(二) 闭包及应用
  2. 深度学习:循环神经网络(RNN)
  3. Mathcad绘制三维曲面图
  4. HDU6072 Logical Chain
  5. 服务器是计算机网络的信息与管理中心,网络信息中心主要职能(8页)-原创力文档...
  6. oracle的用户和mysql的用户_oracle数据库的用户以及表空间
  7. python编辑快速上手_Python编程如何快速上手,答案在这里
  8. 硬盘服务器作用,文件服务器有什么作用?
  9. 微信小程序时间轴demo_微信小程序 - 时间轴(组件)
  10. php data取年月,PHP-date函数 年、月、日参数详解