delete和delete[]

c++中对new申请的内存的释放方式有delete和delete[两种方式,到底这二者有什么区别呢?ios

1.咱们一般从教科书上看到这样的说明:
delete 释放new分配的单个对象指针指向的内存
delete[] 释放new分配的对象数组指针指向的内存
那么,按照教科书的理解,咱们看下下面的代码:
int *a = new int[10];
delete a; //方式1
delete [] a; //方式2
确定会有不少人说方式1确定存在内存泄漏,是这样吗?c++

(1). 针对简单类型 使用new分配后的不论是数组仍是非数组形式内存空间用两种方式都可 如:
int *a = new int[10];
delete a;
delete [] a;
此种状况中的释放效果相同,缘由在于:分配简单类型内存时,内存大小已经肯定,系统能够记忆而且进行管理,在析构时,系统并不会调用析构函数,
它直接经过指针能够获取实际分配的内存空间,哪怕是一个数组内存空间(在分配过程当中 系统会记录分配内存的大小等信息,此信息保存在结构体_CrtMemBlockHeader中,
具体状况可参看VC安装目录下CRT\SRC\DBGDEL.cpp)数组

(2). 针对类Class,两种方式体现出具体差别
当你经过下列方式分配一个类对象数组:
class A
{
private:
char *m_cBuffer;
int m_nLen;
public:
A(){ m_cBuffer = new char[m_nLen]; }
~A() { delete [] m_cBuffer; }
};
A *a = new A[10];
delete a; //仅释放了a指针指向的所有内存空间 可是只调用了a[0]对象的析构函数 剩下的从a[1]到a[9]这9个用户自行分配的m_cBuffer对应内存空间将不能释放 从而形成内存泄漏
delete [] a; //调用使用类对象的析构函数释放用户本身分配内存空间而且 释放了a指针指向的所有内存空间
因此总结下就是,若是ptr表明一个用new申请的内存返回的内存空间地址,即所谓的指针,那么:
delete ptr 表明用来释放内存,且只用来释放ptr指向的内存。
delete[] rg 用来释放rg指向的内存,!!还逐一调用数组中每一个对象的destructor!!
对于像int/char/long/int*/struct等等简单数据类型,因为对象没有destructor,因此用delete 和delete [] 是同样的!可是若是是C++对象数组就不一样了!函数

关于 new[] 和 delete[],其中又分为两种状况:(1) 为基本数据类型分配和回收空间;(2) 为自定义类型分配和回收空间学习

对于 (1),上面提供的程序已经证实了 delete[] 和 delete 是等同的。可是对于 (2),状况就发生了变化。spa


咱们来看下面的例子,经过例子的学习了解C++中的delete和delete[]的使用方法操作系统

 1 #include <iostream>
 2 using namespace std;  3 /////////class Babe
 4 class Babe  5 {  6 public:  7  Babe()  8  {  9         cout << \"Create a Babe to talk with me\" << endl;
10  } 11     ~Babe() 12  { 13         cout << \"Babe don\'t Go away,listen to me\" << endl;
14  } 15 }; 16 //////////main function
17 int main() 18 { 19     Babe* pbabe = new Babe[3]; 20  delete pbabe; 21     pbabe = new Babe[3]; 22  delete pbabe[]; 23     return 0; 24 } 25 
26 
27 结果是: 28 
29 Create a babe to talk with me 30 
31 Create a babe to talk with me 32 
33 Create a babe to talk with me 34 
35 Babe don\'t go away,listen to me
36 
37 Create a babe to talk with me 38 
39 Create a babe to talk with me 40 
41 Create a babe to talk with me 42 
43 Babe don\'t go away,listen to me
44 
45 Babe don\'t go away,listen to me
46 
47 Babe don\'t go away,listen to me

你们都看到了,只使用delete的时候只出现一个 Babe don\'t go away,listen to me,而使用delete[]的时候出现3个 Babe don\'t go away,listen to me。不过无论使用delete仍是delete[]那三个对象的在内存中都被删除,既存储位置都标记为可写,可是使用delete的时候只调用了pbabe[0]的析构函数,而使用了delete[]则调用了3个Babe对象的析构函数。你必定会问,反正无论怎样都是把存储空间释放了,有什么区别。答:关键在于调用析构函数上。此程序的类没有使用操做系统的系统资源(好比:Socket、File、Thread等),因此不会形成明显恶果。若是你的类使用了操做系统资源,单纯把类的对象从内存中删除是不稳当的,由于没有调用对象的析构函数会致使系统资源不被释放,若是是Socket则会形成Socket资源不被释放,最明显的就是端口号不被释放,系统最大的端口号是65535(216 _ 1,由于还有0),若是端口号被占用了,你就不能上网了,呵呵。若是File资源不被释放,你就永远不能修改这个文件,甚至不能读这个文件(除非注销或重器系统)。若是线程不被释放,这它总在后台运行,浪费内存和CPU资源。这些资源的释放必须依靠这些类的析构函数。因此,在用这些类生成对象数组的时候,用delete[]来释放它们才是王道。而用delete来释放也许不会出问题,也许后果很严重,具体要看类的代码了.线程

指针

相关文章
相关标签/搜索