C++常见的内存分配方式有三种:

  • 从静态存储区分配,这里主要是存储局部static对象,类的static成员以及定义在函数之外的变量;
  • 从栈内存分配,这里主要是存储函数内的非static对象;
  • 从堆内存动态分配

其中,静态存储区以及栈内存中的对象,都是由编译器自动创建和销毁,而堆内存中的对象都是由程序显示控制的,通常都是new创建delete销毁或者malloc创建free销毁。动态内存的管理非常棘手,如果动态地创建了对象却没有显式得销毁,就会发生内存泄漏;如果在还有指针引用的时候释放了内存就会出现引用非法内存的指针。

C++11提供了两种智能指针用于管理动态对象,他们可以自动的释放所指向的对象,不用再人为显式地手动销毁,他们都定义在memory头文件中:

  • shared_ptr,允许多个指针指向同一个对象:

    shared_ptr<string> p; //可以指向string的shared_ptr

    shared_ptr支持的操作:

    void sharedPtrTest(){
    //make_shared函数的作用是:
    // 在堆中分配一个对象并初始化它,并返回指向该对象的shared_ptr
    shared_ptr<int> p1 = make_shared<int>();
    shared_ptr<int> p2 = make_shared<int>(); //在条件判断中使用智能指针,相当于检测它是否为空
    //如果只能指针没有指向任何内容,返回false,否则返回true
    if (p1 && p2){
    //解引用智能指针,用法与普通指针一样,获得它指向的对象
    cout << *p1 << endl;//output:0 //返回p中保存的指针
    cout << p2.get() << endl;//output:002FB464(vs2013) //交换,也可以写作p1.swap(p2)
    swap(p1, p2);
    cout << *p1 << " " << *p2 << endl; //output: 1 0
    } //智能指针的拷贝赋值,递增p1的引用计数,此之后p1被引用2次,p2被引用1次
    shared_ptr<int> p3(p1); //返回p1共享智能指针的数量,即p1指向对象被引用次数
    cout << p1.use_count() << endl; //output: 2
    cout << p2.use_count() << endl; //output: 1 //如果只有自己指向这个对象,返回true,否则false
    cout << p1.unique() << endl; //output: 0,说明 p1不是独占对象的
    cout << p2.unique() << endl; //output: 1,说明p2独占对象
    }

再说说引用计数,每个shared_ptr可以看作有一个关联的计数器,保存着这个指针指向的动态内存内的对象被引用的次数,即有多少个智能指针指向它,当变为0即没有指针指向它时这块内存会被自动释放。而只要还有智能指针指向它,它就不会被释放。

  • unique_ptr,该指针会独占指向的对象,不允许其他指针引用,用法基本与shared_ptr相同,但是由于它是独占对象,所以不能进行拷贝赋值以及引用计数相关操作。

    void uniquePtrTest(){
    unique_ptr<int> p1(new int()); //p1.release()返回指向该内存指针,将p1置为空,表示p1放弃控制权
    //此行代码表示p1转移出去对该对象的所有权给p2,即p1置空返回指针赋值给p2
    unique_ptr<int> p2(p1.release());
    cout << *p2 << endl; //output:42 unique_ptr<int> p3(new int()); //释放p2原指向对象,将p3置空,其指向的对象赋值给p2,reset()也可以没有参数,那么久只释放p2原有对象,不对其赋新值
    p2.reset(p3.release());
    cout << *p2 << endl; //output:10 }

【C++】动态内存与智能指针的更多相关文章

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

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

  2. 12.动态内存和智能指针、 直接管理内存、shared_ptr和new结合使用

    12.动态内存和智能指针 1.智能指针分为两种shared_ptr和unique_ptr,后者独占所指向的对象.智能指针也是模板,使用时要用尖括号指明指向的类型.类似emplace成员,make_sh ...

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

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

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

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

  5. 必须要注意的 C++ 动态内存资源管理(二)——指针对象简单实现

    必须要注意的 C++动态内存资源管理(二)——指针对象简单实现 四.拷贝类型的资源         上节我们说过,对于图片类型的资源我们有时候往往采用拷贝(如果对于那种公共图片,可能采用唯一副本,提供 ...

  6. c++ boost库学习二:内存管理->智能指针

    写过C++的人都知道申请和释放内存组合new/delete,但同时很多人也会在写程序的时候忘记释放内存导致内存泄漏.如下所示: int _tmain(int argc, _TCHAR* argv[]) ...

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

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

  8. [C++ Primer] : 第12章: 动态内存

    动态内存与只能指针 静态内存用来保存局部static对象, 类static数据成员以及定义在任何函数之外的变量. 栈内存用来保存定义在函数内的非static对象. 分配在静态或栈内存中的对象由编译器自 ...

  9. 【C++】C++中的动态内存解析

    目录结构: contents structure [-] 动态内存和智能指针 使用shared_ptr管理内存 使用new直接管理内存 shared_ptr和new结合使用 unique_ptr we ...

随机推荐

  1. 1^b+2^b+3^b+...+n^b数列

    首先,这是我自己推出来的,O(n^2),常数巨大.所以无能为力优化!所以求此数列的公式!求优化!!! 主要思想:要算b次的,那么就要先算b+1次的. 首先,我用F(i, j)表示杨辉三角第i层第j个, ...

  2. Qt SizePolicy 属性

    控件的sizePolicy说明控件在布局管理中的缩放方式.Qt提供的控件都有一个合理的缺省sizePolicy,但是这个缺省值有时不能适合 所有的布局,开发人员经常需要改变窗体上的某些控件的sizeP ...

  3. kvm安装

    基础环境: 192.168.1.67                  super67 硬件cpu需要支持:Intel VT-x 技术 本实验使用虚拟机VMware Workstation上的虚拟机 ...

  4. Shrink磁盘

      30857(分区的总容量) =  10160(可修改的这个10610表示Shrink之后的空闲分区) + 20697(Shrink之后分区中占用掉的容量)

  5. git 远程仓库ssh方式

    用ssh-keygen生成公匙和私钥 d:\c\learnc>ssh-keygen Generating public/private rsa key pair. Enter file in w ...

  6. PHP 开启短标签

    <?=STATIC_URL?> 让上面的语句可以正常运行,等同于下面的语句 <?php echo STATIC_URL;?> 可以在 php.ini 中找到 short_ope ...

  7. css实现文字过长省略显示

    .simpleName { width:110px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; } <div cl ...

  8. typecho流程原理和插件机制浅析(第一弹)

    typecho流程原理和插件机制浅析(第一弹) 兜兜 393 2014年03月28日 发布 推荐 5 推荐 收藏 24 收藏,3.5k 浏览 虽然新版本0.9在多次跳票后终于发布了,在漫长的等待里始终 ...

  9. Yii2目录结构

    assets   前端资源文件夹,大致用于管理css js等前端资源文件等 commands   包含命令行命令  文件为控制器文件 config 应用程序的配置文件 controllers 控制器文 ...

  10. Java单链表的实现

    将结点Node进行封装,假设Node的操作有增加,删除,查找,打印几个操作.将Node实现为链表Link的内部类,简化代码. package Chapter5; import java.securit ...