我们的程序使用内存包含以下几种:

  1. 静态内存用来保存局部static对象、类static数据成员以及定义在任何函数之外的变量,在使用之前分配,在程序结束时销毁。
  2. 栈内存用来保存定义在函数内部的非static对象,仅在其定义的程序块运行时才存在。
  3. 堆内存用来存储动态分配的对象,即那些在程序运行时分配的对象,动态对象的生存周期由程序控制,当动态对象不再使用时,我们的代码必须显式的销毁他们。
 
在c++中,普通对象离开它的作用域之后,它的的析构函数会自动调用,从而销毁这个对象,释放它所占用的内存,不会发生内存泄露。为了更容易的使用动态内存,新的标准库提供了两种智能指针类型来管理动态对象。分别为shared_ptr允许多个指针指向同一个对象,unique_ptr独占所指向的对象。
 
一、shared_ptr类
1、创建智能指针
  1. shared_ptr<string> p1; //指向string
  2. shared_ptr<list<int>> p2;//指向int的list

解引用一个智能指针返回它指向的对象

2、基本用法
成员函数有:
 
 
make_shared函数:
最安全的分配和使用动态内存的方法是调用make_shared标准库函数,此函数在动态内存中分配一个对象并初始化它,返回指向此对象的shared_ptr,定义方式为:
 
  1. shared_ptr<vector <int>> vec = make_shared<vector <int>>();  //不传递任何参数,对象进行值初始化
  2. shared_ptr<int> p1 = make_shared<int>(1);      //指向一个1的int的shared_ptr
 
实现智能指针原理:
我们可以认为shared_ptr有一个关联的计数器,称为引用计数。无论何时我们拷贝一个shared_ptr,计数器都会递增,例如用一个shared_ptr初始化另一个shared_ptr,或将它作为参数传递给一个函数以及作为函数的返回值,它所关联的计数器都会递增,当我么给shared_ptr赋予一个新值或是shared_ptr被销毁时,计数器递减。一旦一个shared_ptr的计数器变为0时,它就会自动释放自己所管理的对象(通过析构函数)。shared_ptr还会自动释放相关联的内存。
 
二、unique_ptr类
某个时刻只能有一个unique_ptr指向一个给定对象,当unique_ptr被销毁时,它所指向的对象也被销毁。
1、创建unique_ptr指针
初始化必须采用直接初始化形式,并且不支持普通的拷贝和赋值操作
  1. unique_ptr<double> p1;   //指向double,初始化为一个空指针
  2. unique_ptr<int> p2(new int(1));   //p2指向一个值为1的int

2、基本用法

成员函数:

 

普通指针与智能指针用法示例

 
  1. #include "stdafx.h"
  2. #include <vector>
  3. #include <iostream>
  4. #include <memory>
  5. using namespace std;
  6. vector<int> alloc_new()      //使用内置指针
  7. {
  8. vector<int> *vec = new vector<int>;
  9. return *vec;
  10. delete vec;
  11. }
  12. vector<int> alloc_shared()
  13. {
  14. shared_ptr<vector <int>> vec=make_shared<vector <int>>();    //使用智能指针
  15. return *vec;
  16. }
  17. vector<int> input(vector<int> &ve)
  18. {
  19. ve = alloc_new();
  20. int i;
  21. while (cin >> i)
  22. {
  23. ve.push_back(i);
  24. }
  25. return ve;
  26. }
  27. void print(vector<int> pvec)
  28. {
  29. pvec = input(pvec);
  30. for (auto it = pvec.begin(); it != pvec.end(); it++)
  31. cout << *it << endl;
  32. }
  33. int _tmain(int argc, _TCHAR* argv[])
  34. {
  35. vector<int> i;
  36. print(i);
  37. return 0;
  38. }

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

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

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

  5. Binder学习笔记(十一)—— 智能指针

    轻量级指针 Binder的学习历程爬到驱动的半山腰明显感觉越来越陡峭,停下业务层的学习,补补基础层知识吧,这首当其冲的就是智能指针了,智能指针的影子在Android源码中随处可见.打开framewor ...

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

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

  7. C语言学习笔记--动态内存分配

    1. 动态内存分配的意义 (1)C 语言中的一切操作都是基于内存的. (2)变量和数组都是内存的别名. ①内存分配由编译器在编译期间决定 ②定义数组的时候必须指定数组长度 ③数组长度是在编译期就必须确 ...

  8. linux kernel学习笔记-5内存管理_转

    void * kmalloc(size_t size, gfp_t gfp_mask); kmalloc()第一个参数是要分配的块的大小,第一个参数为分配标志,用于控制kmalloc()的行为. km ...

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

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

随机推荐

  1. Java设计模式六大原则之场景应用分析

    定义:不要存在多于一个导致类变更的原因. 通俗的说.即一个类仅仅负责一项职责. 问题由来:类T负责两个不同的职责:职责P1,职责P2.当由于职责P1需求发生改变而须要改动类T时,有可能会导致原本执行正 ...

  2. PLSQL Developer连接不上64位Oracle 10g的解决办法

    下载instantclient-basic-win32-10.2.0.4.zip 假设Oracle 10g的安装目录为D:\oracle\product\10.2.0\db1 首先,将instantc ...

  3. Linux 系统安装配置PHP服务(源码安装)

    简介: PHP(外文名:PHP: Hypertext Preprocessor,中文名:“超文本预处理器”)是一种通用开源脚本语言.语法吸收了C语言.Java和Perl的特点,利于学习,使用广泛,主要 ...

  4. Storm概念、原理详解及其应用(一)BaseStorm

    本文借鉴官文,添加了一些解释和看法,其中有些理解,写的比较粗糙,有问题的地方希望大家指出.写这篇文章,是想把一些官文和资料中基础.重点拿出来,能总结出便于大家理解的话语.与大多数“wordcount” ...

  5. R语言curve绘图函数

    curve 函数常用于绘制函数对应的曲线,确定函数的表达式,以及对应的需要展示的起始坐标和终止坐标,curve函数就会自动化的绘制在该区间内的函数图像 基本用法,代码示例: curve(sin, -2 ...

  6. Java Number类

    一般地,当需要使用数字的时候,我们通常使用内置数据类型,如:byte.int.long.double等. 例如: int i = 5000; float gpa = 13.65; byte mask ...

  7. css 设置背景图片铺满固定不动

    #page{ position: relative; width: 100%; height: 100%; background-image:url(../img/bg.JPG); backgroun ...

  8. 内存管理 初始化(六)vmalloc_init 及 ioremap

    是不是我错了,本想这个函数会如网上所说将进行非连续内存管理的初始化,但是对于2.6.34的ARM架构而言,该函数实际完成的业务非常少. 内存管理的初始化读到此处,我感觉原有的认识存在很大缺陷: (1) ...

  9. swift闭包的另一种用法

    这不是教程. 当你碰到函数参数需要传递一个闭包(closure)时,一般是可以直接这么传递的(假定无返回): // 教程一般教你在参数位置传递closure: someMethod(arg1, arg ...

  10. Node.js版本管理工具 nvm

    1. 下载安装 curl curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.1/install.sh | bash wge ...