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. BZOJ1092 : [SCOI2003]蜘蛛难题

    按时间一步一步模拟. 每一次,首先将所有没有水但是可以被灌到水的管子标记为有水,然后求出有水的管子里水面高度的最小值. 如果$a$号管有水且最小值为$b$,那么说明此时蜘蛛碰到了水. 如果有管子溢出且 ...

  2. (转)Hbase shell 常用命令(1)

    Hbase shell 常用命令(1) link:http://blog.csdn.net/scutshuxue/article/details/6988348 下面我们看看HBase Shell的一 ...

  3. try {}里有一个return语句,那么紧跟在这个try后的finally {}里的code会不会被执行,什么时候被执行,还是在return之后执行?

    这是一个很有趣的问题,我测试的结果是:是在return中间执行. 我在网上搜寻了一些资料,下面是参考代码: /** * */ package com.b510.test; /** * try {}里有 ...

  4. CentOS GO 语言环境的搭建

    go 语言源码安装依赖 ,gcc ,make glibc库,等,上述工具安装省略, 这个是官方地址:http://www.golang.org/ 另外,其源代码更新采用的是mercurial 工具,安 ...

  5. iOS中--NSArray调用方法详解 (李洪强)

    下面的例子以     NSArray *array = [NSArray arrayWithObjects:@"wendy",@"andy",@"to ...

  6. 将组策略中的内容导出至CSV格式

    #将组策略首选项中的"本地用户和组"下的所有条目导出 $xml = Get-GPOReport -ReportType Xml -Name "China Desktop ...

  7. MSF命令 收集

    一.msfconsole ?   帮助菜单 back 从当前环境返回 banner   显示一个MSF banner cd   切换目录 color   颜色转换 connect   连接一个主机 e ...

  8. CSS兼容性

    1,浮动 ie6中,设置浮动的元素,width自动包裹内容了.通常我们要设定一下这个元素的宽度 子元素浮动父容器高度不能自适应的CSS解决方法 网页前端工作者经常会遇到子元素设置float浮动后导致父 ...

  9. Git学习记录

    一.简要说明 Git是分布式版本控制系统,而非集中式版本控制系统.其优势如下: 自由和开放源码 速度快,体积小 隐式备份(每台用户机上都有一个备份) 安全 不需要强大的硬件 更简单的分支 二.基本概念 ...

  10. python 使用多线程进行压力测试

    #coding=utf-8 import urllib2 import threading import time TOTAL = 0 #总数 SUCC = 0 #响应成功数 FAIL = 0 #响应 ...