为什么new的普通数组用delete 和 delete[]都能正确释放
由同事推荐的一篇博客:
为何new出的对象数组必须要用delete[]删除,而普通数组delete和delete[]都一样-------_CrtMemBlockHeader
文章解释了delete 内部是怎么操作的,讲解也很生动形象。不过看了以后,我只知道了对象数组 用 delete 为什么不行,但是还是不知道普通数组为什么可以用delete[];
文章问的不正确,应该是 为何new出的有析构函数的对象数组必须要用delete[]删除。
经过试验,只有 new 有析构函数(不管是程序员显式定义的 还是由编译器创建的nontrival的析构函数(《深度探索C++对象模型》)) 的对象数组才会记录对象个数。普通数组和没有析构函数的对象数组都不会。
而这就是要记录对象数组个数的原因,就是为了要执行析构函数。就要要知道要执行几次析构函数。
是要定义 delete [] 的原因,就是为了迎合 c++ 的 class 的析构函数的执行。
为什么普通数组释放 delete 和 delete[] 都一样
没有找到delete[]的具体实现 调试也进不去 所以下面的都是我猜想的==,根据上面那篇文章
delete 是默认调用一次析构函数,如果有需要调用的话;
但是delete[] 是根据 存的数组个数 调用几次析构函数,当然如果没有存对象数组的个数,也就不需要调用析构函数了。
如果是delete p;
不管p是什么 都把指针往前移动多少 8*4个字节,在清空内存之前 会先判断某个值是不是对的。
如果是delete[] p;
是不是先检查p是不是有析构函数的对象数组,
如果是的话就往前移动 9*4个字节,然后将前8*4个字节当作头,将 (数组元素个数+<yout data>)整个数据当成 pUserData,然后再进行析构函数的调用 和 一次性释放内存。
如果不是的话,就调用delete p;
为什么 new[]/delete[] 需要记录对象个数?
作者:陈硕
链接:https://zhuanlan.zhihu.com/p/22455100
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
对于有 non-trivial destructor 的 class T, 现在通常的 C++ 实现会在 new[] 的时候多分配 sizeof(size_t) 字节用于保存数组大小,
在 delete[] 的时候会依次逆序调用数组中各对象的析构函数。有的文献管这多分配的几个字节叫 new cookie (Itanium C++ ABI)。
那或许有人会问,既然根据数组首地址就能知道分配了多少字节内存,那为什么 new[] 还需要再保存对象的数目?
这不是多余吗?直接用 内存长度 / sizeof(T) 不就可以算出需要析构多少个对象了?
原因很简单:
内存长度 / sizeof(T) >= 对象个数
因为 new / malloc 在分配内存的时候会 round up 到某个数的倍数(8 或 16 等,跟 malloc 具体实现有关),
即 内存长度 = round_up(sizeof(T) * 对象个数),那么反过来我们就不能用内存长度算出对象个数了,必须单独保存对象个数。
假如不采用 new cookie,如果 sizeof(Foo) == 4,那么 Foo* p = new Foo[28];
会分配 112 字节来构造 28 个对象,但实际会从 libc 拿到 116 字节,那么 delete[] p; 会析构 116/4 = 29 个对象,这就有大问题了。
因此,通常的 C++ 实现在必要时会在 new[] 的时候多分配 sizeof(size_t) 字节用于保存对象数目,而不是让 delete[] 依靠内存大小来算出需要析构多少个对象。
还看了一篇 可以参考下:
浅谈 C++ 中的 new/delete 和 new[]/delete[]
为什么new的普通数组用delete 和 delete[]都能正确释放的更多相关文章
- delete和delete[] 区别
// DeleteAndDelete[].cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <Windows.h> ...
- js中数组删除 splice和delete的区别,以及delete的使用
var test=[];test[1]={name:'1',age:1};test[2]={name:'2',age:2};test[4]={name:'3',age:3}; console.log( ...
- [skill] C++ delete VS delete []
delete 用来删除 new 返回的对象. 先调用对象的析构,然后释放指针指向的内存. delete[] 用来删除 new [] 返回的对象. 先调用数组中每一个对象的析构,然后释放指针指向的内存.
- 【转】 C++中delete和delete[]的区别
一直对C++中的delete和delete[]的区别不甚了解,今天遇到了,上网查了一下,得出了结论.做个备份,以免丢失. C++告诉我们在回收用 new 分配的单个对象的内存空间的时候用 delete ...
- C++:delete和delete[]释放内存的区别
C++告诉我们在回收用 new 分配的单个对象的内存空间的时候用 delete,回收用 new[] 分配的一组对象的内存空间的时候用 delete[]. 关于 new[] 和 delete[], ...
- C++中delete和delete[]的区别
C++告诉我们在回收用 new 分配的单个对象的内存空间的时候用 delete,回收用 new[] 分配的一组对象的内存空间的时候用 delete[]. 关于 new[] 和 delete[],其中又 ...
- 关于delete和delete[]
[精彩] 求问delete和delete[] 的区别??http://www.chinaunix.net/jh/23/311058.html C++告诉我们在回收用 new 分配的单个对象的内存空间的 ...
- C++中delete和delete[]的使用
偶然的机会要使用到动态分配整形数组,怎么删除new出来的东西一时有点模糊(也许一直就不知道),于是在VS上试了试(写代码时经常用这种方法去验证模凌两可的东西),总结出来有两点. 1.基本数据类型new ...
- C++中delete 和delete[]的区别
c++告诉我们在回收new分配的单个对象的内存空间的时候用delete, 回收new[ ]分配的一组对象的内存空间的时候用 delete[ ]; #include <iostream> ...
随机推荐
- 详述JavaScript数组
摘要 数组是JavaScript中的常用类型,本文详述了数组的基本知识以及一些常用的数组方法,并对每种方法进行了详细解释 数组定义 用字面量直接定义 var arr=[0,0,0]; //注意,是方括 ...
- 一个简单的使用restc demo
最近不经意间看到饿了么团队开发的restc,接口调试工具(类似postman),其实调试接口都没用过工具,每次都只是运行起项目直接调接口.闲来无事,看到restc,就决定试试,后面觉得挺不错的,就分享 ...
- ThinkPhp 源码阅读心得
php 中header 函数 我可能见多了,只要用来跳转.今天在阅读TP源码的时候发现,header函数有第三个参数.有些困惑所以找到手册查阅下,发现 void header ( string $st ...
- AndroidStudio引入so文件
项目中需要引入几个 so文件,但APP一直崩溃报错 java.lang.UnsatisfiedLinkError: Couldn't load ad from loader dalvik.system ...
- hdu1037
#include <iostream> #include <cstdio> using namespace std; int main() { int a,b,c; while ...
- InnoDB的Named File Formats
随着InnoDB存储引擎的发展,新的页数据结构有时用来支持新的功能特性.比如前面提到的InnoDB Plugin,提供了新的页数据结构来支持表压缩功能,完全溢出的(Off page)大变长字符类型字段 ...
- 写一个MyList
首先定义接口 using System; using System.Collections.Generic; using System.Linq; using System.Text; using S ...
- keychain的使用
通常情况下,我们用NSUserDefaults存储数据信息,但是对于一些私密信息,比如密码.证书等等,就需要使用更为安全的keychain了.keychain里保存的信息不会因App被删除而丢失,在用 ...
- [转]学好Mac常用命令,助力iOS开发
转自:http://www.jianshu.com/p/d9ec00d28237 序言 在iOS开发的过程中,更多地注重iOS开发的效率,熟练使用Mac终端操作的常用命令,可以让你更好的游刃于iO ...
- [转]numpy性能优化
转自:http://blog.csdn.net/pipisorry/article/details/39087583 http://blog.csdn.net/pipisorry/article/de ...