[c++] delete 和 delete []的区别

整理摘自:https://www.cnblogs.com/wangjian8888/p/7905176.html

1. 区别

1. delete 释放new分配的单个对象指针指向的内存;

1)对于简单类型,内存大小已确定,析构时系统可直接通过指针获取实际分配的内存空间并释放;

2)对于类对象数组,仅调用数组首对象的析构函数,剩下对象的空间不能被释放;

2. delete[] 释放new分配的对象数组指针指向的内存。

1)对于简单类型,效果同delete,可以释放数组内存空间;

2)对于类对象数组,将逐一调用数组中每个对象的析构函数,释放了指针指向的全部内存空间。

2. 针对简单类型

1 int *a = new int[10];
2 delete a;
3 delete []a;

这种情况下释放效果相同,原因在于:分配简单类型内训时,内存大小已经确定,系统可以记忆并且进行管理,在析构时,系统并不会直接调用析构函数,它直接通过指针获取实际分配的内存空间,(数组的内存空间也同样会被系统记录,保存在结构体CrtMemBlockHeader中)。

3. 针对类对象数组

 1 class A
 2 {
 3 private:
 4     char *m_cBuffer;
 5     int m_nLen;
 6 public:
 7     A() {m_cBuffer = new char[m_nLen]; }
 8     ~A() {delete [] m_cBuffer;}          
 9 };
10 
11 A *a = new A[10];
12 delete a;  // (1)
13 delete []a; //(2)

对于(1), 仅释放了a指针指向的全部内存空间,即为调用了a[0]对象的析构函数;

但是剩余的a[1], ..., a[9]这9个对象自行分配的m_cBuffer对应的内存空间将不能释放。

g++11 编译通过,运行报错:*** Error in `./delete_test': double free or corruption (fasttop): 0x0000000000ef4c20 ***

对于(2), 调用类对象的析构函数释放对象自己分配的内存空间,可以逐一调用数组中每个对象的析构函数,释放了a指针指向的全部内存空间。

4. 示例说明

 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     /* (1) */
20     // Babe* pbabe1 = new Babe[3];
21     // delete pbabe1;
22 
23     /* (2) */
24     Babe* pbabe2 = new Babe[3];
25     delete [] pbabe2;
26     return 0;
27 }
28 
29 /* (1) Output: */
30 // Create a Babe to talk with me
31 // Create a Babe to talk with me
32 // Create a Babe to talk with me
33 // Babe don't go away,listen to me
34 // *** Error in `./delete_test': munmap_chunk(): invalid pointer: 0x00000000018a6c28 ***
35 
36 /* (2) Output: */
37 // Create a Babe to talk with me
38 // Create a Babe to talk with me
39 // Create a Babe to talk with me
40 // Babe don't go away,listen to me
41 // Babe don't go away,listen to me
42 // Babe don't go away,listen to me

原博客中显示结果不同,在用g++11编译通过,运行时 (1) 报错。

在对数组释放空间时,建议选用delete [], 如果程序的类使用了操作系统的系统资源(Socket, File, Thread等),使用delete[]会使得对象逐一调用析构函数,释放系统资源。