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

  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. pandas 的算术运算和数据对齐

    pandas 还有一个重要的功能,就是他可以对不同索引的对象进行算数运算.对象相加, 如果存在不同的索引对,则结果的索引就是该索引对的并集. 先来个例子 Series In [33]: s1 = Se ...

  2. c 预处理的宏定义

    概念 以“#”号开头的都是预处理命令 例如 #include <stdio.h>宏定义 宏定义无参数的宏名后不带参数# 表示这是一条预处理命令, define 为宏定义命令.“标识符”为所 ...

  3. (笔记)Mysql命令drop table:删除数据表

    drop table命令用于删除数据表. drop table命令格式:drop table <表名>; 例如,删除表名为 MyClass 的表:    mysql> drop ta ...

  4. Unity------Unity 脚本基类 MonoBehaviour 与 GameObject 的关系

    Unity 脚本基类 MonoBehaviour 与 GameObject 的关系 标签: unity脚本 2017-03-27 12:55 395人阅读 评论(0) 收藏 举报  分类: Unity ...

  5. (转)Ubuntu12.04上NFS Server安装使用过程

    原文链接:Ubuntu12.04上NFS Server安装使用过程 实现步骤: 1.服务器端:sudo apt-get install portmap2.服务器端:sudo apt-get insta ...

  6. 让不支持MVC3的服务器/空间/虚拟主机 支持MVC3 (前提是必须支持 .net 4.0才可以)

    在有的时候,你用的VPS,服务器或者是虚拟空间可能是没有安装MVC3的,下面我们就自己来手动来让虚拟空间支持(前提是空间必须是.net 4.0的,因为MVC3是在4.0下运行) 我们先在web.con ...

  7. Xianfeng轻量级Java中间件平台:基于RBAC模型实现权限控制的原理

    首先,白话一下RBAC模型.RBAC是基于角色的访问控制(Role-Based Access Control)的简称.RBAC认为权限授权实际上是Who.What.How的问题.在RBAC模型中,wh ...

  8. 使用ssh-keygen和ssh-copy-id三步实现SSH无密码登录

    ssh-keygen  产生公钥与私钥对. ssh-copy-id 将本机的公钥复制到远程机器的authorized_keys文件中,ssh-copy-id也能让你有到远程机器的home, ~./ss ...

  9. thinkphp 配置加载

    状态配置 每个应用都可以在不同的情况下设置自己的状态(或者称之为应用场景),并且加载不同的配置文件. 举个例子,你需要在公司和家里分别设置不同的数据库测试环境.那么可以这样处理,在公司环境中,我们在入 ...

  10. Java编程思想学习笔记——初始化与清理(二)

    成员初始化 Java尽力保证:所有变量在使用前都能得到适当的初始化. 方法的局部变量:未初始化,编译错误. void f(){ int i; // System.out.println(i);//编译 ...