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. Nginx模块之ngx_http_proxy_module

    ngx_http_proxy_module模块: 示例: location / { proxy_pass http://localhost:8000; proxy_set_header Host $h ...

  2. 调用手机摄像头并上传图片--jquery ajax

    1.图片框样式与进度条样式 .alert_img_content { width: 44%; float: left; margin: 3%; border: 1px solid #ddd; back ...

  3. 用cookie存值

    ////用Request获取到客户端Cookie 判断是否为空 //if (Request.Cookies["CheckTime"] == null) //{ // //创建Coo ...

  4. vConsole 让你在手机上也能轻松调试网页

    有时候为了想在手机真机上对网页进行 Debug,可手机上没有 F12,用 Chrome DevTools 连接手机操作又太过复杂.VConsole 的出现,正好解决了这一痛点! (下列内容照搬一下官方 ...

  5. Android 基础知识 -- Linux环境搭建

    Android 开发工具下载网站:http://www.androiddevtools.cn/ 1 JDK 1.1 下载JDK,解压后放到/usr/lib/jvm/目录 sudo mv jdk1.7. ...

  6. nginx反向代理https访问502, nginx反向代理, 支持SNI的https回源,SNI源点,nginx反向代理报错

    正常nginx配置了SSL是可以通过HTTPS访问后端的,但是对有配置SNI + https后端的支持有点麻烦. 编译安装nginx后,看一下是否支持SNI /usr/local/nginx/sbin ...

  7. php7 安装redis拓展

    配置之前应该是环境已经搭好了,phpinfo的页面可以加载出来.   使用git clone下载git上的phpredis扩展包 git clone  https://github.com/phpre ...

  8. Microsoft Visual Studio 显示行号

    工具下面有一个选项

  9. win10驱动签名禁用与启动

    禁用:https://jingyan.baidu.com/article/624e74594dbc8d34e8ba5aa6.html?qq-pf-to=pcqq.c2c 启用或恢复:https://z ...

  10. 解决lucene更新删除无效的问题

    个人博客 地址:http://www.wenhaofan.com/article/20180921233809 问题描述 在使用deleteDocuments,updateDocument方法根据id ...