简介

C++没有内存自动回收机制,对堆内存的管理就是简单的new和delete,每次new出来的内存都需要手动delete释放。但由于忘记、流程复杂或者异常退出等,都有可能导致没有执行delete释放内存,造成内存泄漏。

在实际工程中,我们往往希望将精力放在应用层上而不是费劲心思处理语言的细枝末节(内存释放),于是就有了最原始的智能指针auto_ptr。

智能指针原理

智能指针是一种资源管理类,这个类在构造函数中传入一个原始指针,在析构函数中释放传入的指针。智能指针都是栈上的对象,所以当函数(或者程序)结束时,会自动释放。

通过对*和->的重载,使类的对象具有指针的特性。

auto_ptr源码

下面是侯捷《STL源码剖析》使用的sgi-stl-v2.91版的auto_ptr源码实现,这个版本的可读性非常好,可惜该版本还没有出现shared_ptr和unique_ptr指针,而新版的源码这部分的实现可读性不太友好。所以这里只能呈现auto_ptr的源码,有助于理解只能指针的原理。

template<class X>
class auto_ptr {
private:
X* ptr;
mutable bool owns;
public:
typedef X element_type;
explicit auto_ptr(X* p = ) __STL_NOTHROW : ptr(p), owns(p) {}
auto_ptr(const auto_ptr& a) __STL_NOTHROW : ptr(a.ptr), owns(a.owns) {
a.owns = ;
}
template<class T> auto_ptr(const auto_ptr<T>& a) __STL_NOTHROW
: ptr(a.ptr), owns(a.owns) {
a.owns = ;
} auto_ptr& operator=(const auto_ptr& a) __STL_NOTHROW {
if (&a != this) {
if (owns)
delete ptr;
owns = a.owns;
ptr = a.ptr;
a.owns = ;
}
}
template<class T> auto_ptr& operator=(const auto_ptr<T>& a) __STL_NOTHROW {
if (&a &= this) {
if (owns)
delete ptr;
owns = a.owns;
ptr = a.ptr;
a.owns = ;
}
}
~auto_ptr() {
if (owns)
delete ptr;
} X& operator*() const __STL_NOTHROW { return *ptr; }
X* operator->() const __STL_NOTHROW { return ptr; }
X* get() const __STL_NOTHROW { return ptr; }
X* release() const __STL_NOTHROW { owns = false; return ptr; }
};

注意:虽然本文主要分析auto_ptr的源码,但不要用auto_ptr ! 在c++11已经弃用。

C++11中常用的智能指针

C++中常用的智能指针有,在C++11中的<memory>中有unique_ptr、shared_ptr、weak_ptr

1. unique_ptr:同一时刻只能由唯一的unique_ptr指向给定对象,不支持拷贝和赋值操作。

2. shared_ptr:可以有多个指针指向相同的对象,通过引用计数机制,支持拷贝和赋值操作。每使用一次,内部引用计数器加1,析构一次,引用计数减1,当计数为0时,释放所指的堆空间。

3. weak_ptr:弱引用。引用计数器有一个问题就是相互引用形成环,这样两个指针指向的内存都无法释放。需要手动打破循环引用或者使用weak_ptr。顾名思义,weak_ptr是一个弱引用,只引用不计数。如果一块内存被shared_ptr和weak_ptr同时引用,当所有的shared_ptr析构了之后,不管还有没有weak_ptr引用该内存,内存也会被释放,所以weak_ptr不保证它指向的内存一定有效,在使用之前需要检查weak_ptr是否为空指针。

智能指针分析及auto_ptr源码的更多相关文章

  1. JPEG概述和头分析(C源码)

    原创文章,转载请注明:JPEG概述和头分析(C源码)  By Lucio.Yang 部分内容来自:w285868925,JPEG压缩标准 1.JPEG概述 JPEG是一个压缩标准,又可分为标准 JPE ...

  2. Android5.1.1 - APK签名校验分析和修改源码绕过签名校验

    Android5.1.1 - APK签名校验分析和修改源码绕过签名校验 作者:寻禹@阿里聚安全 APK签名校验分析 找到PackageParser类,该类在文件“frameworks/base/cor ...

  3. 百度智能手环方案开源(含源码,原理图,APP,通信协议等)

    分享一个百度智能手环开源项目的设计方案资料. 项目简介 百度云智能手环的开源方案是基于Apache2.0开源协议,开源内容包括硬件设计文档,原理图.ROM.通讯协议在内的全套方案,同时开放APP和云服 ...

  4. 【校招面试 之 C/C++】第25题 C++ 智能指针(一)之 auto_ptr

    1.智能指针背后的设计思想 我们先来看一个简单的例子: void remodel(std::string & str) { std::string * ps = new std::string ...

  5. Cesium专栏-填挖方分析(附源码下载)

    Cesium 是一款面向三维地球和地图的,世界级的JavaScript开源产品.它提供了基于JavaScript语言的开发包,方便用户快速搭建一款零插件的虚拟地球Web应用,并在性能,精度,渲染质量以 ...

  6. Proxy Server源码及分析(TCP Proxy源码 Socket实现端口映射)

    版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/u014530704/article/de ...

  7. NIO 源码分析(05) Channel 源码分析

    目录 一.Channel 类图 二.begin 和 close 是什么 2.1 AbstractInterruptibleChannel 中的 begin 和 close 2.2 Selector 中 ...

  8. NIO 源码分析(02-2) BIO 源码分析 Socket

    目录 一.BIO 最简使用姿势 二.connect 方法 2.1 Socket.connect 方法 2.2 AbstractPlainSocketImpl.connect 方法 2.3 DualSt ...

  9. NIO 源码分析(02-1) BIO 源码分析

    目录 一.BIO 最简使用姿势 二.ServerSocket 源码分析 2.1 相关类图 2.2 主要属性 2.3 构造函数 2.4 bind 方法 2.5 accept 方法 2.6 总结 NIO ...

随机推荐

  1. Android: samil语法指令集-基于dex文件结构的寄存器虚拟机

    Smali文件结构解   Smali文件与java中的类是一一对应的,包括内部类和匿名内部类也会生成对应的smali文件(典型的比如实现某个接口的匿名内部类),所以你会看到.smali文件比.java ...

  2. javaweb和数据库的简易商城系统

    这是一个基于Javaweb和数据库的简易商城系统.为大二夏季小学期完成. 目录结构 主要功能截图为: 一.购买用户 1.首页(除此界面其余界面访问需要登录才能进入) 查看商品 添加购物车 查看购物车 ...

  3. Jmeter工具做接口测试

    一.安装Jmeter 1.安装JDK ①下载jdk,到官网下载jdk,地址:http://jmeter.apache.org/download_jmeter.cgi ② 安装jdk(Oracle官网下 ...

  4. 使用python播放音乐

    1.首先安装pygame,pip install pygame 2.上代码: import time import pygame #音乐路径 filepath=r"C:\Users\1473 ...

  5. redis基础操作概念等笔记

    Redis常用配置 daemonize ->是否是后台进程 port ->对外端口 logfile ->Redis 系统日志 dir ->Redis 工作目录 Redis的链接 ...

  6. openfalcon架构及相关服务配置详解(转)

    一:openfalcon组件 1.falcon-agent 数据采集组件 agent内置了一个http接口,会自动采集预先定义的各种采集项,每隔60秒,push到transfer. 2.transfe ...

  7. 0ctf-Wallbreaker Easy复现

    补坑+1. 有预留的后门,并且给了phpinfo,因此可以从phpinfo中先搜集一波信息: 这里禁用了很多命令执行的函数,所以应该要bypass_disablefunction,先读一下flag在哪 ...

  8. ubuntu 安装eclipse for c++

    linux的GUI和windos比起来实在逊色,虽然它的终端模式(命令行模式)非常强大.linux发行版ubuntu的GUI相对其他版本要华丽一些,所以最近由redhat转向ubuntu进行linux ...

  9. 20191121-5 Scrum立会报告+燃尽图 02

    此作业要求参见https://edu.cnblogs.com/campus/nenu/2019fall/homework/10066 一.小组情况 组长:贺敬文组员:彭思雨 王志文 位军营 徐丽君队名 ...

  10. 记录一次webpack3升级到webpack4过程

    升级之前也参考了一些网上的教程.借鉴之,进行的自己的升级.一些版本为什么设为那个版本号也是参考别人的结果. 整体是按照先升级npm run dev:在升级npm run build的顺序. 首先升级w ...