12.动态内存和智能指针

1.智能指针分为两种shared_ptr和unique_ptr,后者独占所指向的对象。智能指针也是模板,使用时要用尖括号指明指向的类型。类似emplace成员,make_shared用其参数来构造给定类型的对象。(make_shared创建一个对象并将之初始化,返回一个指向该类型的指针。

2.每个智能指针都有一个关联的计数器,称为引用计数,用来记录有多少个shared_ptr指向相同得对象3.p.use_count(),当计数值为零时,其析构函数将自动释放对象和相关联的内存。为减少资源浪费,要记得删除那些不需要的share_ptr.

4.使用动态内存的一个常见原因是允许多个对象共享相同的状态。为了实现我们所希望的数据共享,我们为每个类的对象设置一个shared_ptr来管理类。

12.1.2 直接管理内存

1.因为在自由空间分配的内存是无名的,因此new 无法为其分配的对象命名,而是返回一个指向该对象的指针,若是不用delete(调用析构函数) 来操作该指针,新分配的这块内存将始终存在(即使改变指针的指向或指针失效),这就是内存泄漏问题,还有一个空悬指针问题就是在释放该内存后,未能将所有原指向该内存的所有指针置为空,而使某些指针仍指向原来那块内存。(free不调用析构函数)

2.我们可以使用直接初始化的方式来初始化一个动态分配的对象

如:int* p = new int(3);,

int *p(new int(42));

3.此外,还有默认初始化和值初始化,默认初始化的内存对象值是未定义的,而值初始化的内存对象的值是良好定义的。建议对动态分配的内存进行初始化。

int *pi = new int;                        //默认初始化,值未定义

int *pi2 = new int();      //值初始化,值是良好定义的,为0

4.我们也可以使用auto来从初始化器的值推断出我们想要分配的对象的类型int *p = new auto (3),但初始化器若是一个初始值列表时,则不能用auto来推断(因为auto推断不出来,不知道是vector还是其他的什么)

5.用new动态分配const对象是合法的:const int *pci = new const int(1024),但必须对该内存执行初始化。

6.delete p可以销毁给定指针所指向的对象,释放该对象的内存,但是delete只能对指向动态分配的内存的指针或空指针操作,否则行为未定义,另外,不能多次delete指向同一块内存的指针。

7.指向new分配的内存的指针是内置指针(普通指针),指向make_shared分配的内存的指针是智能指针。智能指针用make_shared或new的返回值来初始化。建议使用智能指针,从而避免内存泄漏和空悬指针等问题。

12.1.3 shared_ptr和new结合使用

1.不存在从普通指针到智能指针的相互转化的构造函数

2.shared_ptr<T>p(q),若q为内置指针,则应该只有两种选择new T ()或shared_ptr<T>(p);第一种是直接初始化,第二种是显示转化。

3.智能指针的初始化:shared_ptr<int> p1(new int(1024);

Shared_ptr<int> p2(make_shared<int> (2014);

Shared_ptr<int>p3 = make_shared<int> (1024);

推荐使用make_shared

4.p.reset()函数,作用是使p和参数的指向相同,会影响引用计数,所以当参数列表为空时,p = nullptr,p原来所指对象会因引用计数为0而被释放,参数列表为内置指针和智能指针时,其作用可想而知。

5.int *x(new int(1024));是危险的,因为x是一个普通指针,而不是一个智能指针。

6.当将一个shared_ptr绑定到一个普通指针时,我们就将内存的管理责任交给了这个shared_ptr。之后,我们就不应该再使用内置指针来访问那块内存了。

7.p.get()函数,返回一个和p指向相同的内置指针,同样影响引用计数,

8.判断一个shared_ptr指针是否是指向该对象的唯一指针,可以用p.unique(),但是用p.use_count() == 1没那么好。

const char *s1 = "hello world";s1是常量指针

12.动态内存和智能指针、 直接管理内存、shared_ptr和new结合使用的更多相关文章

  1. 【C++】动态内存与智能指针

    C++常见的内存分配方式有三种: 从静态存储区分配,这里主要是存储局部static对象,类的static成员以及定义在函数之外的变量: 从栈内存分配,这里主要是存储函数内的非static对象: 从堆内 ...

  2. C++相关:动态内存和智能指针

    前言 在C++中,动态内存的管理是通过运算符new和delete来完成的.但使用动态内存很容易出现问题,因为确保在正确的时间释放内存是及其困难的.有时候我们会忘记内存的的释放,这种情况下就会产生内存泄 ...

  3. 【足迹C++primer】39、动态内存与智能指针(3)

    动态内存与智能指针(3) /** * 功能:动态内存与智能指针 * 时间:2014年7月8日15:33:58 * 作者:cutter_point */ #include<iostream> ...

  4. c++学习笔记—动态内存与智能指针浅析

    我们的程序使用内存包含以下几种: 静态内存用来保存局部static对象.类static数据成员以及定义在任何函数之外的变量,在使用之前分配,在程序结束时销毁. 栈内存用来保存定义在函数内部的非stat ...

  5. c++智能指针(unique_ptr 、shared_ptr、weak_ptr、auto_ptr)

    一.前序 什么是智能指针? ——是一个类,用来存储指针(指向动态分配对象也就是堆中对象的的指针). c++的内存管理是让很多人头疼的事,当我们写一个new语句时,一般就会立即把delete语句直接也写 ...

  6. c++智能指针的使用,shared_ptr,unique_ptr,weak_ptr

    c++智能指针的使用 官方参考 普通指针的烦恼:内存泄漏,多次释放,提前释放 智能指针 负责自动释放所指向的对象. 三种智能指针 shared_ptr,unique_ptr,weak_ptr: 将sh ...

  7. boost的线程池和内存池 智能指针

    内存池为boost自带的 #include <boost/pool/pool.hpp> 或者另外一个开源的库: nedmalloc 一个高效率的库 线程池需要下载另外一个开源库 http: ...

  8. C++11智能指针(unique_ptr、shared_ptr、weak_ptr)(转)

    原文地址:https://blog.csdn.net/king_way/article/details/95536938

  9. Qt 智能指针学习(7种指针)

    Qt 智能指针学习 转载自:http://blog.csdn.net/dbzhang800/article/details/6403285 从内存泄露开始? 很简单的入门程序,应该比较熟悉吧 ^_^ ...

随机推荐

  1. vue项目中使用element ui上传图片到七牛

    1.获取token值 后台有接口调用直接返回token值 //请求后台拿七牛云token async getQiniuToken() { //token let uploadtoken = await ...

  2. 2020牛客寒假算法基础集训营4-I 匹配星星【贪心】

    链接:https://ac.nowcoder.com/acm/contest/3005/I来源:牛客网 示例1 输入 复制 2 1 1 0 2 2 1 2 1 1 0 2 2 1 输出 复制 1 1 ...

  3. Spring 理解和开始

    1.先看看Spring的历史吧 https://baijiahao.baidu.com/s?id=1620099105315862154&wfr=spider&for=pc 2.Spr ...

  4. Mysql快速入门(二)

    多表关联查询 JOIN 按照功能大致分为如下三类: CROSS JOIN(交叉连接) INNER JOIN(内连接或等值连接). OUTER JOIN(外连接) 交叉连接 交叉连接的关键字:CROSS ...

  5. CSS: inline、block和inline-block的区别

    block 块级元素特点: 1.每个块级元素都从新的一行开始,并且其后的元素也另起一行.(很霸道,一个块级元素独占一行) 2.元素的高度.宽度.行高以及顶和底边距都可设置. 3.元素宽度在不设置的情况 ...

  6. 题解【洛谷P2264】情书

    题面 看到每一单词在同一句话中出现多次感动值不叠加,一眼想到 \(\text{set}\). 首先将词汇列表中的单词存储起来,我用的是 \(\text{set}\). 对于每一个句子的单词,我们可以先 ...

  7. PYthon之路Day12

    生成器 核心:生成器的本质就是一个迭代器 程序员自己写的一种迭代器 作用:节省空间 生成器可以使用for进行遍历 生成器编写方式: 基于函数编写 def func():    print('这是一个函 ...

  8. ORA-12638: 身份证明检索失败

    PLSQL 连接Oracle时提示 “ORA-12638: 身份证明检索失败” 错误, 但是开发IDE可以正常连接,DataGrid 可以正常连接,所以确定是本地设置问题. 网上搜了一下,说是因为Or ...

  9. phpstorm对比代码

    方法一 首先在phpstorm中左侧的资源管理器中,按住键盘上的CTRL键选中两个文件,然后鼠标右键,点击菜单中的"Compare Tow Files",就可以了,如下图 方法二 ...

  10. python接口自动化之发送get(三)

    1.安装requests requests是python的第三方库,需要进行安装.安装之前最好先关闭fiddler cmd(win+R快捷键)输入:pip install requests 其他命令: ...