array new 与 array deletedelete
以前在看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];
的内存结构,可以发现是这样的:

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

可以看到,对于内存而言,delete一定会将Cookie标记段给释放掉,如果是类似Complex的数组,那么使用delete与delete[]的效果是一致的,但是针对String这类含指针类型的数组,使用delete仅执行首次析构,也就是在这里出现了内存泄漏。
最近怎么关心内存泄漏了?
程序跑了一晚上泄漏了8G内存,不关心一下怎么得了。
array new 与 array deletedelete的更多相关文章
- Array.prototype.slice && Array.prototype.splice 用法阐述
目的 对于这两个数组操作接口,由于不理解, 往往被误用, 或者不知道如何使用.本文尝试给出容易理解的阐述. 数组 什么是数组? 数组是一个基本的数据结构, 是一个在内存中依照线性方式组织元素的方式, ...
- 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 ...
- sklearn中报错ValueError: Expected 2D array, got 1D array instead:
from sklearn.linear_model import LinearRegression lr = LinearRegression() print(tr_x.shape,tr_y.shap ...
- From Ruby array to JS array in Rails- 'quote'?
From Ruby array to JS array in Rails- 'quote'? <%= raw @location_list.as_json %>
- ES6数组的扩展--Array.from()和Array.of()
一. Array.from() : 将伪数组对象或可遍历对象转换为真数组 1.何为伪数组 如果一个对象的所有键名都是正整数或零,并且有length属性,那么这个对象就很像数组,语法上称为"类 ...
- es6 --数组--Array.from() 、Array.isArray()、Array.of()、find()、findIndex()、fill()、entries() 、keys() ,values()
将两类对象转为真正的数组 Array.from()方法用于将两类对象转为真正的数组:类似数组的对象(array-like object)和可遍历(iterable)的对象(包括ES6新增的数据结构Se ...
- Array.of()和Array()区别
Array.of方法用于将一组值,转换为数组. Array.of(3, 11, 8) // [3,11,8] Array.of(3) // [3] Array.of(3).length // 1 这个 ...
- [Python] Indexing An Array With Another Array with numpy
NumPy Reference: Indexing Integer array indexing: Select array elements with another array def index ...
- JavaScript Array vs new Array区别
规范说明 When Array is called as a function rather than as a constructor, it creates and initialises a n ...
- 决策树python建模中的坑 :ValueError: Expected 2D array, got 1D array instead:
决策树python建模中的坑 代码 #coding=utf-8 from sklearn.feature_extraction import DictVectorizerimport csvfrom ...
随机推荐
- java javacv调用摄像头并拍照
调用摄像头并拍张照片,我一开始用的java的jmf媒体框架,但这个有很多的局限性不好使并且很有麻烦,兜了一圈发现javacv东西,研究之后这东西简单,方便:废话不多说了来重点. javacv官网:点击 ...
- JSONP跨域的原理解析( 一种脚本注入行为)
JavaScript是一种在Web开发中经常使用的前端动态脚本技术.在JavaScript中,有一个很重要的安全性限制, 被称为“some-Origin Policy”(同源策略).这一策略对于Jav ...
- 数据库SQL
mySQL的安装和简单的命令 show -uroot -p 进入mySQL show databases 查看所有库 show tables 查看所有表 use 表名 进入表 create datab ...
- 配置tomcat解压版
配置Tomcat[解压版] 选择解压版的Tomcat的理由是可以让我们使用多个Tomcat,但是配置上就会出现一些问题,需要我们手动进行更改配置.我的Tomcat版本是:apache-tomcat-6 ...
- SVN常用问题汇总
参考文档.http://www.cnblogs.com/newsea/archive/2012/04/28/2474818.html 1.客户端取消记住用户名和密码. 2.汉化后设置为中文
- 通过外部配置文件做mybatis的基础配置,以及Mapper代理接口的实现
1.通过外部配置文件做mybatis的基础性的配置. 1)先编写config.properties的文件(做一些动态的配置). 配置的内容如下: jdbc.jdbcUrl=jdbc:oracle:th ...
- .net 常用的命名空间和类
一.基础命名空间 l System.Collections 包含了一些与集合相关的类型,比如列表,队列,位数组,哈希表和字典等. l System.IO 包含了一些数据流类型并提供了文件和目录同步 ...
- Python处理json格式的数据文件(一些坑、一些疑惑)
这里主要说最近遇到的一个问题,不过目前只是换了一种思路先解决了,脑子里仍然有疑惑,只能怪自己太菜. 最近要把以前爬的数据用一下了,先简单的过滤一下,以前用scrapy存数据的时候为了省事也为了用一下它 ...
- python中zipfile文件名编码的问题
在python中编程导入压缩包,利用zipfile包,从zipinfo读取文件名总是出错,创建的文件名是乱码,写入pgsql更是出错. 但在ubuntu下测试却正常,在windows下测试总是失败. ...
- set命令
set命令简介 set命令是shell中初学者比较少接触,但是却很有用的一个命令(这里我们说的shell指的是bash).set命令是shell解释器的一个内置命令,用来设置shell解释器的属性,从 ...