delete和delete[]的区别

转载 2016年08月29日 14:58:23

转载地址:http://blog.csdn.net/hazir/article/details/21413833
C++中,类型分为两种:内置类型和自定义的类类型。在释放内存时分为释放内置类型和自定义类型的数组。
1、对于单个对象,释放内置类型和类类型的方法一样,使用delete.对于类对象而言,delete做两件事:
(1)调用类的析构函数;
(2)释放对象的内存;
2、对于动态申请到的数组,调用delete[]进行释放

string *psa = new string[10];      
int *pia = new int[10];     
delete [] psa;
delete [] pia;     

上面在申请一个数组时都用到了 new [] 这个表达式来完成,第一个数组是 string 类型,分配了保存对象的内存空间之后,将调用 string 类型的默认构造函数依次初始化数组中每个元素;第二个是申请具有内置类型的数组,分配了存储 10 个 int 对象的内存空间,会进行默认初始化,但由于在函数内部,默认初始化为未定义。

都用到 delete [] 表达式,注意这地方的 [] 一般情况下不能漏掉!我们也可以想象这两个语句分别干了什么:第一个对 10 个 string 对象分别调用析构函数,然后再释放掉为对象分配的所有内存空间;第二个因为是内置类型不存在析构函数,直接释放为 10 个 int 型分配的所有内存空间。

这里对于第一种情况就有一个问题了:我们如何知道 psa 指向对象的数组的大小?怎么知道调用几次析构函数?
这个问题直接导致我们需要在 new [] 一个类对象数组时,需要保存数组的维度,C++ 的做法是在分配数组空间时多分配了 4 个字节的大小,专门保存数组的大小,在 delete [] 时就可以取出这个保存的数,就知道了需要调用析构函数多少次了。
在delete[]时,这里要注意的两点是:调用析构函数的次数是从数组对象指针前面的 4 个字节中取出;传入 operator delete[] 函数的参数不是数组对象的指针 pAa,而是 pAa 的值减 4。

为什么 new/delete 、new []/delete[] 要配对使用?

int *pia = new int[10];
delete []pia;

这肯定是没问题的,但如果把 delete []pia; 换成 delete pia; 的话,会出问题吗?
但如果不调用析构函数呢(如内置类型,这里的 int 数组)?我们在 new [] 时就没必要多分配那 4 个字节, delete [] 时直接释放为 int 数组分配的空间。如果这里使用 delete pia;那么将会调用 operator delete 函数,传入的参数是分配给数组的起始地址,所做的事情就是释放掉这块内存空间。所以不存在问题的。这里说的使用 new [] 用 delete 来释放对象的提前是:对象的类型是内置类型或者是无自定义的析构函数的类类型!

class A *pAa = new class A[3];
delete pAa;

那么 delete pAa; 做了两件事:

1、调用一次 pAa 指向的对象的析构函数;
2、调用 operator delete(pAa); 释放内存。

显然,这里只对数组的第一个类对象调用了析构函数,后面的两个对象均没调用析构函数,如果类对象中申请了大量的内存需要在析构函数中释放,而你却在销毁数组对象时少调用了析构函数,带来以下缺点:
1、这会造成内存泄漏
2、上面的问题你如果说没关系的话,那么第二点就是致命的了!直接释放 pAa 指向的内存空间,这个总是会造成严重的段错误,程序必然会奔溃!因为分配的空间的起始地址是 pAa 指向的地方减去 4 个字节的地方。你应该传入参数设为那个地址!只释放了4字节之后的第一个对象,相当于内存中就中断了部分,造成段错误

sql中 truncate 和 delete 有什么区别

  • 2011年05月27日 14:30
  • 21KB
  • 下载

sql之truncate、delete与drop区别

  • 2012年03月06日 10:40
  • 5KB
  • 下载

GET,POST,PUT,DELETE的区别

Http定义了与服务器交互的不同方法,最基本的方法有4种,分别是GET,POST,PUT,DELETE。URL全称是资源描述符,我们可以这样认为:一个URL地址,它用于描述一个网络上的资源,而HTTP...

sql之truncate_、delete与drop区别.pdf

  • 2011年04月22日 10:01
  • 54KB
  • 下载

Rest模式——get,put,post,delete含义与区别

POST   /uri     创建   DELETE /uri/xxx 删除    PUT    /uri/xxx 更新或创建   GET    /uri/xxx 查看   GET操作是安全的。...

new/delete 和malloc/free 的区别一般汇总

一、基本概念      malloc/free: 1、函数原型及说明:       void *malloc(long NumBytes):该函数分配了NumBytes个字节,并返回...
  • jw903
  • jw903
  • 2014年05月16日 09:19
  • 561

在c#中 RemoveAt、 Remove、delete用法区别

删除DataRow:有两种方法可以删除DataRow,分别是Delete方法和Remove方法和RemoveAt方法。 其区别是: Delete方法实际上不是从DataTable中删除掉一行,而是...

new/delete 和malloc/free 的区别一般汇总

原文:http://www.cnblogs.com/biyeymyhjob/archive/2012/07/16/2593754.html 一、基本概念      malloc/free: 1、函数...

Oracle数据库中truncate命令和delete命令的区别

首先讲一下,truncate命令: 语法:TRUNCATE  TABLE  table; 表格里的数据被清空,存储空间被释放。 运行后会自动提交,包括之前其它未提交的会话,因而一旦清空无法回退。...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:delete和delete[]的区别
举报原因:
原因补充:

(最多只允许输入30个字)