以前在看C++书和上C++课的时候可以看到

delete[] pointer;

的用法,而大多数对于这个用法没有具体的解释,多是看到:

有一个delete运算符的特殊语法,可以释放动态分配的数组内存:

delete[] p_numbers;

方括号告诉编译器,指针指向了一个数组,而不是单个值。

引文自:《C++程序设计:现代方法》,14.2 指针和数组

也没有说明如果缺少[]会带来的后果,猜想是内存泄露,但是不明就里,于是给我来带了C++内存管理诡谲的印象。不过最近侯捷先生的讲解却很是清晰。

下方所说Complex类为仅包含两个double类型成员,String仅含一个char类型指针。

构造##

首先说的是构造,以Complex类为例:

Complex *c = new Complex(1,2);

执行过程为:

Complex *c;
void* mem = operator new( sizeof(Complex) ); //内部调用malloc(n),分配内存
c = static_cast<Complex*>(mem); //类型转换
c->Complex::Complex(1,2); //→Complex::Complex(c,1,2),构造函数

那么在内存中执行的时候分配内存为:

红色部分为操作系统分配之Cookie,蓝色部分为填充位,目的是为了让整个长度为16的倍数。灰色区域内数据仅在Debug模式下出现,绿色区域为对象所占长度。可计算,Debug模式下的Complex实例长度为:

8[两个双精度浮点实数] + (32+4)[调试模式] + (4×2)[Cookie] → 52 + 12[填充] → 40H

那么此时向操作系统取内存时Cookie末位置1,即Cookie为00000041,释放时末位置0。之所以保持16(10H)的倍数即如此。

Release下的String类型长度则为:

4[指针] + (4×2)[Cookie] → 12 + 4[填充] → 10H

释放##

执行

String *s = new String(1,2);

delete s;

delete s的时候会:

String::~String(s);     //析构函数
operator delete(s); //释放内存,其内部调用free(s)

即执行String类析构函数后释放内存,释放Cookie标记段。看起来似乎没什么问题。

数组##

看一下

Complex *c = new Complex [3];

String *s = new String [3];

的内存结构,可以发现是这样的:

在顶部多存储了一个数组长度。那么执行deletedelete[]有什么区别呢?是这样的:

可以看到,对于内存而言,delete一定会将Cookie标记段给释放掉,如果是类似Complex的数组,那么使用deletedelete[]的效果是一致的,但是针对String这类含指针类型的数组,使用delete仅执行首次析构,也就是在这里出现了内存泄漏。


最近怎么关心内存泄漏了?

程序跑了一晚上泄漏了8G内存,不关心一下怎么得了。

array new 与 array deletedelete的更多相关文章

  1. Array.prototype.slice && Array.prototype.splice 用法阐述

    目的 对于这两个数组操作接口,由于不理解, 往往被误用, 或者不知道如何使用.本文尝试给出容易理解的阐述. 数组 什么是数组? 数组是一个基本的数据结构, 是一个在内存中依照线性方式组织元素的方式, ...

  2. Array.length vs Array.prototype.length

    I found that both the Array Object and Array.prototype have the length property. I am confused on us ...

  3. sklearn中报错ValueError: Expected 2D array, got 1D array instead:

    from sklearn.linear_model import LinearRegression lr = LinearRegression() print(tr_x.shape,tr_y.shap ...

  4. From Ruby array to JS array in Rails- 'quote'?

    From Ruby array to JS array in Rails- 'quote'? <%= raw @location_list.as_json %>

  5. ES6数组的扩展--Array.from()和Array.of()

    一. Array.from() : 将伪数组对象或可遍历对象转换为真数组 1.何为伪数组 如果一个对象的所有键名都是正整数或零,并且有length属性,那么这个对象就很像数组,语法上称为"类 ...

  6. es6 --数组--Array.from() 、Array.isArray()、Array.of()、find()、findIndex()、fill()、entries() 、keys() ,values()

    将两类对象转为真正的数组 Array.from()方法用于将两类对象转为真正的数组:类似数组的对象(array-like object)和可遍历(iterable)的对象(包括ES6新增的数据结构Se ...

  7. Array.of()和Array()区别

    Array.of方法用于将一组值,转换为数组. Array.of(3, 11, 8) // [3,11,8] Array.of(3) // [3] Array.of(3).length // 1 这个 ...

  8. [Python] Indexing An Array With Another Array with numpy

    NumPy Reference: Indexing Integer array indexing: Select array elements with another array def index ...

  9. JavaScript Array vs new Array区别

    规范说明 When Array is called as a function rather than as a constructor, it creates and initialises a n ...

  10. 决策树python建模中的坑 :ValueError: Expected 2D array, got 1D array instead:

    决策树python建模中的坑 代码 #coding=utf-8 from sklearn.feature_extraction import DictVectorizerimport csvfrom ...

随机推荐

  1. java javacv调用摄像头并拍照

    调用摄像头并拍张照片,我一开始用的java的jmf媒体框架,但这个有很多的局限性不好使并且很有麻烦,兜了一圈发现javacv东西,研究之后这东西简单,方便:废话不多说了来重点. javacv官网:点击 ...

  2. JSONP跨域的原理解析( 一种脚本注入行为)

    JavaScript是一种在Web开发中经常使用的前端动态脚本技术.在JavaScript中,有一个很重要的安全性限制, 被称为“some-Origin Policy”(同源策略).这一策略对于Jav ...

  3. 数据库SQL

    mySQL的安装和简单的命令 show -uroot -p 进入mySQL show databases 查看所有库 show tables 查看所有表 use 表名 进入表 create datab ...

  4. 配置tomcat解压版

    配置Tomcat[解压版] 选择解压版的Tomcat的理由是可以让我们使用多个Tomcat,但是配置上就会出现一些问题,需要我们手动进行更改配置.我的Tomcat版本是:apache-tomcat-6 ...

  5. SVN常用问题汇总

    参考文档.http://www.cnblogs.com/newsea/archive/2012/04/28/2474818.html 1.客户端取消记住用户名和密码. 2.汉化后设置为中文

  6. 通过外部配置文件做mybatis的基础配置,以及Mapper代理接口的实现

    1.通过外部配置文件做mybatis的基础性的配置. 1)先编写config.properties的文件(做一些动态的配置). 配置的内容如下: jdbc.jdbcUrl=jdbc:oracle:th ...

  7. .net 常用的命名空间和类

    一.基础命名空间 l  System.Collections 包含了一些与集合相关的类型,比如列表,队列,位数组,哈希表和字典等. l  System.IO 包含了一些数据流类型并提供了文件和目录同步 ...

  8. Python处理json格式的数据文件(一些坑、一些疑惑)

    这里主要说最近遇到的一个问题,不过目前只是换了一种思路先解决了,脑子里仍然有疑惑,只能怪自己太菜. 最近要把以前爬的数据用一下了,先简单的过滤一下,以前用scrapy存数据的时候为了省事也为了用一下它 ...

  9. python中zipfile文件名编码的问题

    在python中编程导入压缩包,利用zipfile包,从zipinfo读取文件名总是出错,创建的文件名是乱码,写入pgsql更是出错. 但在ubuntu下测试却正常,在windows下测试总是失败. ...

  10. set命令

    set命令简介 set命令是shell中初学者比较少接触,但是却很有用的一个命令(这里我们说的shell指的是bash).set命令是shell解释器的一个内置命令,用来设置shell解释器的属性,从 ...