你們都知道new
了一個變量,須要使用delete
釋放內存,而new
出了一個數組,須要使用對應的delete[]
釋放內存。但我好像在哪看見過一種說法:針對系統內置類型,使用new分配後的無論是數組仍是非數組形式內存空間用delete
和delete[]
均可以。光說沒用,寫代碼測試一下(測試環境 centos
, g++4.8.5
)。html
內置普通變量:ios
// test.cpp #include <iostream> #include <thread> using namespace std; #define N (1024*1024) // 1M int main() { while(1) { char *a = new char[N]; // 4M //delete[] a; std::this_thread::sleep_for(std::chrono::milliseconds(5)); //5ms延時 printf("running\n"); } } // 編譯 g++ test.cpp -o test -std=c++11 // 1. 不delete時,內存一直在漲 // 2. 使用delete 時, 內存不漲 // 3. 使用delete[] 時, 內存不漲
測試發現,說的確實有道理啊,內置類型的數組不必使用delete[]
。c++
因而再測測自定義類型:centos
#include <iostream> #include <thread> using namespace std; #define N (1024*1024) // 1M class A{ public: char a; A() : a('a') { } }; int main() { while(1) { A *a = new A[N]; // 4M //delete[] a; std::this_thread::sleep_for(std::chrono::milliseconds(5)); //5ms延時 printf("running\n"); } } // 1. 不delete時,內存一直在漲 // 2. 使用delete 時, 內存不漲 // 3. 使用delete[] 時, 內存不漲
what?結果和內置類型同樣???這是爲何,因而趕忙去查一查資料,發現本身對new
和delete
的理解確實錯了!趕忙從新總結一波。數組
記住一句話:new
先分配內存,再調用構造函數。delete
先調用析構函數,再釋放內存。函數
那麼,若是new
了一個數組,調用幾回構造函數呢,調用的是那一個構造函數呢;delete
數組和delete[]
數組又分別調用幾回析構呢。能夠作個實驗:測試
#include <iostream> #include <thread> using namespace std; class String { public: // 若是刪除無參的構造函數 // new String[]的時候會報錯 String() { cout << "String()" << endl; m_data = new char; } String(int n) { cout << "String(int n)" << endl; m_data = new char[n]; } ~String() { cout << "~String()" << endl; delete[] m_data; } private: char* m_data; }; int main() { String* s = new String[3]; // 三次無參構造函數 // delete s; // 一次析構函數 delete[] s; // 三次析構函數 } // 1. new String[3],調用了3次無參的構造函數! // 因此若是沒有無參構造函數會報錯 // error: no matching function for call to 'String::String()' // 2. 使用delete 時,調用了一次構造函數 // 3. 使用delete[] 時, 調用了三次析構函數
其實看完這個例子,就能明白爲何要用delete[]
而不是delete
了,由於只掉用一次析構函數,對於上面的代碼是錯的,會發生內存泄漏。由於String
類中有指針成員。這些指針成員必須跟隨着String
對象的銷燬而銷燬。this
下面是內存分佈圖:spa
在使用delete
的時候,其實是會刪除三個String
對象佔據的內存,可是隻有在調用String
類的析構函數的時候,纔會銷燬對象內部的m_data
變量所指向的字符串。而delete
只會調用第一個對象的析構函數,後面兩個String
對象的析構函數不夠調用。而delete[]
能夠保證這一點。在使用new
的時候,會記錄數組的長度,以下圖,指針
delete[]
會根據記錄的長度決定析構次數。
因此說,其實若是類中沒有new
出來的資源,都是棧上的資源,無需調用構造函數來釋放資源的話,其實調用delete
和delete[]
沒有區別。而若是類中有指針變量,則對於這種對象的數組,必須使用delete[]
。
能夠編寫代碼測試,當一個類中只有棧上的變量的時候,它組成的數組用delete
刪除是不會發生內存泄漏的。引言中的測試也證實了這一點。
緊緊記住:new
先分配內存,再調用構造函數。delete
先調用析構函數,再釋放內存。delete
只會調用數組第一個對象的析構函數,而delete[]
會調用數組中全部對象的析構函數。雖然有時候沒有影響,可是最好仍是遵循規範,防止錯誤的發生,對於數組都使用delete[]
。
[delete 和 delete []的真正區別](https://www.cnblogs.com/wangj...