以前在看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. rpm常用命令

    * 手动安装 rpm 包  `rpm-ivh xxxxx.rpm`  参数:   --force 即使覆盖其他包的文件也没强迫安装   --nodeps 即使依赖包没安装,也被强制安装 * 查看 rp ...

  2. Ext.encode 抛出异常“Uncaught RangeError: Maximum call stack size exceeded”

    在用使用Ext.encode(ExtObject)过程中抛出了如下错误: Uncaught RangeError: Maximum call stack size exceeded 实际上,不能用 E ...

  3. jvm 原理和优化

    在csdn 上看到的,觉得很好,收藏了: 原博文地址: 濤子 http://blog.csdn.net/ning109314/article/details/10411495/ JVM工作原理和特点主 ...

  4. 主机使用代理上网,虚拟机Linux如何连外网

    VMware虚拟机的三种联网方法及原理 一.Brigde--桥接  :默认使用VMnet0 1.原理: Bridge  桥"就是一个主机,这个机器拥有两块网卡,分别处于两个局域网中,同时在& ...

  5. JQuery调用Servlet实现文件下载

    jsp页面上的txt附件,点击后浏览器默认直接打开,结果是乱码. 因为用户上传的txt文件可能是ANSI.Unicode.UTF-8编码的任意一种,上传时后台获取文件内容重写一遍保证浏览器打开正常太过 ...

  6. 七个高效的文本编辑习惯(以Vim为例)

    七个高效的文本编辑习惯 如果你花很多时间输入纯文本.写程序或HTML,那么通过高效地使用一个好的编辑器,你可以节省大部分时间.本文将提供指导和提示,让你更迅速地做这些工作,并且少犯错误. 本文用开源文 ...

  7. 异常:System.Data.EvaluateException: 未找到列[District].

    异常:System.Data.EvaluateException: 未找到列[District]. 这里存在的问题不一定是说,数据源表没有该字段.此问题在于数据库字段包含空格字符.

  8. redis命令总结

     Redis命令总结 redis 127.0.0.1:6379> info  #查看server版本内存使用连接等信息 redis 127.0.0.1:6379> client list  ...

  9. 在虚拟机上安装Linux6.5

    下定决心开始学习Linux了,这个博客将记录我的成长点滴,方便日后温故而知新!并希望有小伙伴能给出意见和建议! 我用的是VMware Workstation 10,当然是破解版,毕竟只是自己做练习使用 ...

  10. Java实现Excel导入数据库,数据库中的数据导入到Excel

    private static void executeMethod(JobExecutionContext arg0) throws Exception{ try { TContrastService ...