简介

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. HDU 5852 Intersection is not allowed! ( 2016多校9、不相交路径的方案、LGV定理、行列式计算 )

    题目链接 题意 : 给定方格中第一行的各个起点.再给定最后一行与起点相对应的终点.问你从这些起点出发到各自的终点.不相交的路径有多少条.移动方向只能向下或向右 分析 : 首先对于多起点和多终点的不相交 ...

  2. BERT中文 添加 early_stop

    Step1:建一个hook early_stopping_hook = tf.contrib.estimator.stop_if_no_decrease_hook( estimator=estimat ...

  3. Sqlite3错误:Recursive use of cursors not allowed 的解决方案

    感悟] 写完这篇日志后,有调了一段时间程序,又有了一点心得分享下: 一)爬稳定的数(dong)据(xi)最好存储下来,特别是数据库在国外的那种,下载时间成本太高昂了,存起来再处理,会节约很多时间: 二 ...

  4. 锁对象Lock-同步问题更完美的处理方式

    Lock是java.util.concurrent.locks包下的接口,Lock 实现提供了比使用synchronized 方法和语句可获得的更广泛的锁定操作,它能以更优雅的方式处理线程同步问题,我 ...

  5. mac 配置apache

    Apache配置 对httpd.conf文件的配置.首先打开 /etc/apache2/httpd.conf文件,也就是Apache2.4的相关配置文件. 连接php 首先我们将相应的PHP版本配置进 ...

  6. React入门----基础篇

    React 背景介绍 React 起源于 Facebook 的内部项目,因为该公司对市场上所有 JavaScript MVC 框架,都不满意,就决定自己写一套,用来架设 Instagram 的网站.做 ...

  7. Android 美团Robust热更新 使用入门

    Android热更新方案Robust 相信很多人都认识了解过 热修复.热更新.热补丁(对于这个技术也没有特别标准的一种叫法,下面我统一叫热更新),之后的一年里,各种热更新方案如雨后春笋般出现,比较耳熟 ...

  8. Android屏幕横竖屏切换和生命周期管理的详细总结

    一般的我们去切换屏幕方向都是不希望Activity被重新创建,这时就需要对一些属性进行设置,或者使用代码设置.        今天想学一下Android屏幕横竖屏切换,但是网上很多知识不准确或不正确, ...

  9. leetcode16 最接近的三数之和

    做了几周的hard之后,这道题居然轻易就解出来了,稍微debug了一下就ac了,算是有了一丢丢提高把: 思路 这道题因为和三数之和很像,所以充分利用双指针的思想:先排序,然后再固定一个数i,i取值从[ ...

  10. vsCode安装todo插件

    使用过IDEA或者WebStrom的阿媛应该都知道他们都有一个TODO功能,方便我们跟踪注释,或者说是我们在项目代码里面所做的标记:但是如果你现在在使用vsCode,你会发现,没有TODO功能,幸好, ...