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來釋放也許不會出問題,也許後果很嚴重,具體要看類的代碼了.線程

指針

相關文章
相關標籤/搜索