new/delete和malloc/free的區別

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];


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章