malloc與free是C++/C語言的標準庫函數。分別負責分配內存和釋放內存。
new/delete是C++的運算符。分別負責分配內存和調用構造函數 以及 調用析構函數和釋放內存;
由於malloc/free是庫函數而不是運算符,不在編譯器控制權限之內,不能夠把執行構造函數和析構函數的任務強加於malloc/free。因此C++語言需要一個能完成動態內存分配和初始化工作的運算符new,以及一個能完成清理與釋放內存工作的運算符delete。注意new/delete不是庫函數
delete只會調用一次析構函數,而delete[]會調用每一個成員的析構函數。
在More Effective C++中有更爲詳細的解釋:“當delete操作符用於數組時,它爲每個數組元素調用析構函數,然後調用operator delete來釋放內存。”
delete與new配套,delete []與new []配套
補充:delete []是如何得知數組個數的
轉載出處:https://blog.csdn.net/lcfeng1982/article/details/8106719
通常在delete[]一個數組時,編譯器要按順序作如下2件事情:
1. 對每個數組元素調用析構函數 。
2. 釋放對象數組所佔內存 。編譯器只需簡單地把數組首地址告訴操作系統,操作系統內部有內存申請情況的記錄(每個申請內存段的首地址,長度,etc..),因此會正確地釋放掉內存.注意整個數組所佔內存是一次釋放掉的,而不是每個元素釋放一次.事實上,在這一步編譯器無需知道數組元素個數.以上2步是彼此獨立的2步. 另外,如果數組元素沒有顯式析構函數(例如char),那麼編譯器就無需作第1步了.在這種情況下,編譯器根本不需要知道數組個數,因此就偷懶不再在數組前面放元素個數n了.
{
public:
TestA(){a=new int(1);}
~TestA(){delete a;}
int* a;
};
memset(pInt, 0, 100*sizeof(int));
int* pr = pInt-1;
int size = *pr;//此處size的值不是100,說明數組前面沒有加上數組個數(因爲int不需要顯示析構函數)
delete []pInt;
TestA* pArT = new TestA[100];
size = sizeof(TestA) * 100;
int* pp = (int*)(pArT) - 1;
size = *pp;//此處size的值是100,說明數組前面加上了數組個數
delete []pArT;
在第1步確實需要知道元素個數.編譯器會把元素個數放在分配的那塊內存的前面,結構形如 :n object1 object2 ... objectn 。另外,不要把這個n和數組內存長度混淆起來。前者是編譯器管理的,後者是操作系統管理的.(如果知道對象的size,是可以從後者計算出前者.遺憾的是,操作系統沒有API提供所申請的內存段的長度,編譯器只好自己記錄)
另外,提醒C++程序員 delete [] p;語句中delete和[]之間一定要有空格
舉例如下:
class TestA
int *pInt = new int[100];