- 首先,new,delete都是c++的關鍵字並不是函數,通過特定的語法組成表達式,new可以在編譯的時候確定其返回值.可以直接使用string *p=new string("asdfgh");來直接賦值。這其中在調用new分配空間得時候的時候,系統其實直接調用了類或結構的構造函數來對對其進行賦值,這個過程就相當於是string p=string("asdfgh"); 或者string p("asdfgh");(其實上面的過程還是有一定的不同之處;一 個顯示式調用,一個隱式調用,兩者都是在進程虛擬地址空間中的棧中分配內存,而第一種使用了new,在堆中分配了內存,而棧中內存的分配和釋放是由系統管 理,而堆中內存的分配和釋放必須由程序員手動釋放,所以這就產生一個問題是把對象放在棧中還是放在堆中的問題,這個問題又和堆和棧本身的區別有關) 對於類和結構體這樣子很方便,對一般的數據類型這樣就沒什么必要了。 在對這樣子的分配空間進行內存釋放的時候直接調用delete來釋放,delete p就可以了。這個過程中,對於一般數據類型就直接釋放,對於類或者結構體delete調用其析構函數類釋放內存。
- 用new來分配多塊內存的時候就要使用new[]來分配,eg:char* p=new char[size];string *p=new string [size];在這個過程中new[]干了兩件事,一個是記錄要分配的數量size,(可以是在分配的內存前一段某個位置額外分配分配了幾個字節來說儲存數據來記錄大小,也可以是在后台專門有一個表來記錄各個數組的大小,這與內存分配器的工作方式有關。你可以以n種方式來實現這個過程,但是必須要能記錄數組的大小)再向系統申請分配內存並返回數組的指針(而不是所有分配的空間的起始地址)。對於結構體或者類,new[]調用構造函數size次,其實質還是記錄大小和分配空間兩件事。對於用new[]分配的內存在釋放的時候就必須用delete[]來釋放,直接delete[] p就可以了。delete[]怎么知道要釋放多大的內存或調用多少次析構函數,就是由於在new分配的時候專門特意的記錄了要分配數組的大小,delete[]的時候就先讀取這個值,然后調用size次析構函數來釋放空間或者根據size來直接釋放空間。
-
void *operator new(size_t); //allocate an object void *operator delete(void *); //free an object void *operator new[](size_t); //allocate an array void *operator delete[](void *); //free an array
這是在c++11 new中對這幾個函數的定義,平時可直接使用,但再次主意new[]分配的只能通過delete[]來釋放,如果用delete的話這只能釋放掉數組的第一項,后邊的還是存在的。因為數組的地址就是數組第一項的地址。所以new[]的一定要用delete[]來釋放。
-
- malloc與free都是c語言中的函數,malloc的返回值為void型,在使用的時候要注意對其進行類型轉換, eg:char* p=(char*)malloc(number*sizeof(char));malloc在分配內存的時候是以字節來分配的。在分配之前也會記錄數組的大小和類型。最后返回一個指向數據區的void型指針。malloc分配的內存必須通過free來釋放。與malloc有關的函數還有calloc與realloc,其中calloc在分配完內存返回指針之前把所有的數據都初始化為0,相當於malloc加上memset。realloc函數可以吧原來分配的好的內存塊的改變大小。動態分配的內存必須是整體一塊釋放,但是realloc可以縮小一小塊動態分配的內存,有效的釋放他尾部的部分內存。
- 關於在調用delete或者free之后系統是否真正的釋放了內存的問題。可以通過程序+任務管理器性能窗口來進行檢測
#include<stdio.h> #include<stdlib.h> #include<Windows.h> char*ch[1000]; int size = 20000; int main() { int i, j; for (int i = 0; i < 1000; i++) ch[i] = (char*)malloc(sizeof(char)*size); for (i = 0; i < 1000;i++)//換入內存,如不進行操作,glibc並不會真正的向系統申請內存 for (j = 0; i < size; j++) ch[i][j] = ' '; Sleep(20000);//在此期間查看內存使用情況 for (i = 0; i < 1000; i++) free(ch[i]); Sleep(20000);//再次查看內存使用情況 return 0; }
實驗發現,free前與free后的內存使用情況是相同,並沒有因為free而空閑出很多內存。而當程序跑完最后的return 0;之后內存使用率才真正的降下來。此時程序涉及到的內存才真正的被完全釋放。所以答案是free並沒有真正釋放內存,相關內存塊儲存的東西仍然在,而free與delete的過程只是切斷了指針與內存塊的聯系,這塊內存本身在沒有其他的數據對其進行修改的時候一直都儲存着其原來的東西。有其他的內存分配需求的時候這塊內存很可能就被分配過去了,然后誰想怎么改就怎么改(就類似於優盤格式化后不向里邊寫入新東西,原來的東西還是存在的一樣)(如果分配到的內存特別特別大的話,free后有可能內存使用率直接降下來,這與操作系統內存管理有關)
- warning: 1.不管是用new還是用malloc在進行內存分配的時候都要先檢查一下是否分配到內存,分配完了之后要趕緊檢查一下返回指針是否為NULL;不管是用free還是用delete或者delete[]釋放完內存之后都要把原本來指針變為空指針,要不然就變成野指針了,很危險。 2.一個new對應一個delete,一個new[]對應一個delete[],一個malloc對應一個free,必須這樣子。要不然會造化內存泄露。也不要對直接定義了的變量或者數組進行free或者delete;不能free一個非malloc返回的指針,不能delete一個非new返回的指針。