以前在看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的更多相关文章

  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. WPF 中使用MVVM模式后,找回ListBox中的ListBoxItem元素

    ListBoxItem lstitem = this.list.ItemContainerGenerator.ContainerFromItem(m) as ListBoxItem; 其中this.l ...

  2. IP地址子网掩码主机地址网络号主机号

    (1)子网掩码1所对应的位为网络号位 而所对应的位为主机号位 IP地址+子网掩码=网络号: IP地址+子网掩码(反码)=主机号. (2)主机号中的m位被用来表示网络号了,也就是子网号,将0-255划分 ...

  3. jquery中的append和appendTo用法

    append(content):向每个匹配的元素内部追加内容.这个操作与对指定的元素执行appendChild方法,将它们添加到文档中的情况类似. JavaScript代码 <script ty ...

  4. sublime text3 less2css rem

    1.下载sublime text3 官网地址:https://www.baidu.com/link?url=2kr0ijQXVL1_6oXdPByYh7ecMl7OUAYVx5fyTNjMrYVdtq ...

  5. MongoDB(NoSQL) 入门

    一.简介 NoSQL数据库因其可扩展性使其变得越来越流行,利用NoSQL数据库可以给你带来更多的好处, MongoDB是一个用C++编写的可度可扩展性的开源NoSQL数据库. 本文主要讲述MongoD ...

  6. JS组件系列——封装自己的JS组件

    前言:之前分享了那么多bootstrap组件的使用经验,这篇博主打算研究下JS组件的扩展和封装,我们来感受下JQuery为我们提供$.Extend的神奇,看看我们怎么自定义自己的组件,比如我们想扩展一 ...

  7. css中图片等比例缩放

    li img{ display: inline-block; max-height: 60px; max-width: 60px; vertical-align: middle; }

  8. ZOJ3792_Romantic Value

    给出图,使得两点无流量,剩余其他边的总容量与删除边数的比值. 要机智啊... 因为原图给的边数不超过1000,容量也不超过1000,可以这样把边的容量变为2000*c+1.这样跑出最大流后,最大流除以 ...

  9. 从0到1搭建移动App功能自动化测试平台(2):操作iOS应用的控件

    转自:http://debugtalk.com/post/build-app-automated-test-platform-from-0-to-1-Appium-interrogate-iOS-UI ...

  10. ORA-01919

    看到这个错误提示再明白不过了,Oracle中某个角色不存在. 不小心把Oracle中的几个重要角色删除掉了(dba,connect,resource),Plsql只能用DBA权限进去,普通权限进不去, ...