首先需要知道,編譯器給變數分配的記憶體分為三部分:靜態儲存區域、棧、堆。
靜態儲存區:主要儲存全域性變數和靜態變數。
棧:呼叫函式相關的變數、位址等,底層對棧提供支援,棧的大小遠小於堆的大小,向負方向生長,限定大小。
堆:儲存動態生成的變數,操作由c/c++函式庫提供,效率低於棧,向正方向生長,無限大小(32位可達4g)。
1.使用new與delete
classname *object=new classname(param);//單個物件
delete object;
object=null;
int *a = new int[5];//陣列
delete a; //釋放int陣列空間
使用new,這個時候系統會呼叫建構函式,此時c++是在堆上開闢了一塊空間來建立物件的,c++用new建立物件時返回的是乙個物件指標(要訪問new所開闢的結構體空間,無法直接通過變數名進行,只能通過賦值的指標進行訪問),物件指標object此時指向乙個classname的物件,c++分配給object的僅僅是存放指標值的空間。需要注意的是,使用完這個物件後,需要手動delete刪除,否則在整個程式生命週期內這個物件都將會占用記憶體,在需要反覆新建物件的工程中,長此以往將會造成記憶體洩漏。delete物件時會呼叫其析構函式,delete結束後指標需要指向null,否則可能誤用此指標。
注意:該方法建立的物件呼叫類方法時,必須用「->」,而不能用「.」。
2.使用建構函式(顯式呼叫和隱式呼叫)
class rec
;main()
用兩種方法建立了乙個myrec物件,實際上這兩種方式是一樣的,一種是顯示呼叫,一種是隱式呼叫,此時如果列印出sizeof(myrec),會得到 8 這個結果。因為myrec中有2個int型別的資料成員,乙個int成員佔4個位元組,所以myrec物件佔8個位元組。
這種方法建立的物件,記憶體分配是分配到棧中的,由c++預設建立和撤銷,自動呼叫建構函式和析構函式
注意:該方法建立的物件呼叫類方法時,必須用「.」,而不能用「->」如myrec.getarea()。
3.使用malloc()與free()
先來看下面的例子:
char *p;//1
p = (char *)malloc(10*sizeof(char));//2
if(p!=null) return;
memset(p,0,10*sizeof(char));//3
stpcpy(p,"come on");//4
p =(char *)realloc(p,20*sizeof(char));//5
if(p!=null) return;
strcat(p,",baby!");//6
free(p);//7
(1)定義乙個char*型指標變數p
(2)為p分配10個位元組的記憶體空間,若申請失敗則退出
(3)用0填充這個記憶體空間
(4)複製"come on" 字串到p指向的記憶體空間
(5)將p指標指向的記憶體空間再擴大20個位元組,若申請失敗則退出
(6)將",baby!"字元複製在p指向空間字串的後面
(7)釋放p指向的空間
*其中引數size_t size表示動態記憶體分配空間的大小,以位元組為單位,c++是在堆上開闢了一塊空間來建立物件的。
size_t 是typedef重定義的型別,重定義這樣資料型別的作用就是讓使用者一目了然,指示使用者這個引數表示乙個長度,在size後加上t,表示是整型相關資料型別的,以後看到***_t的型別,通常都是整型相關資料型別重定義。
malloc()函式的返回值是乙個指標,或者說是分配後記憶體空間的首位址, 如果malloc()函式申請空間成功則返回一段記憶體空間的首位址,失敗則返回null,失敗的原因可能是記憶體不足,為了防止後續的操作出錯,此處申請完記憶體後需要判斷是否申請成功。malloc返回值的型別是void* ,所以在呼叫malloc時要顯式地進行型別轉換,將void * 轉換成所需要的指標型別。
void memset(void s,int c,size_t n)
此函式將已開闢記憶體空間 s 的首 n 個位元組的值設為值 c。一般用在對定義的字串進行初始化為『 』或『/0』,此處為了防止分配的記憶體存在無關內容,首先對其進行清空操作。
void realloc(void mem_address, unsigned int newsize)
功能為改變mem_address所指記憶體區域的大小為newsize長度。如果重新分配成功則返回指向被分配記憶體的指標,否則返回空指標null。此處將原申請空間繼續擴大了。
void free(void ptr)*
功能為釋放掉指定的記憶體空間,其中void *ptr是記憶體空間的首位址,與malloc成對使用。
最後再列一些new與malloc的區別:
1.首先當然是編譯環境的區別,在c++中,兩者都可以使用,而在c中是不支援new的;
2.失敗時的區別,當new失敗時會丟擲bac_alloc異常,而malloc失敗時返回的是空指標;
3.返回值的區別,new返回的指標是與物件匹配的並不需要轉換,而malloc返回的是void型別指標,需要強轉;
4.new和delete會自動呼叫建構函式和析構函式,但是malloc和free不會;
5.malloc可利用realloc重新分配記憶體,new不可以;
6.new的使用比malloc簡單,內部已經實現了大小的計算、型別轉換等工作,而malloc使用時需要計算大小及進行型別轉換;
7.malloc是標準庫函式,new是c++的運算子。所有new可以被過載,但malloc不可以,malloc需要庫函式的支援,new不需要;
8.malloc可利用realloc重新分配記憶體,new不可以;
9.new有明確的方式處理陣列的分配,即new,釋放也有delete,malloc沒有。
記憶體那些事
linux中的free m可以檢視當前的記憶體使用情況 yejianfeng iz23fsd free m total used free shared buffers cached mem 7869 7737 132 0 489 4419 buffers cache 2828 5040 swap ...
記憶體的那些事
堆 heap 為程式儲存的一塊記憶體區域,用來儲存那些在執行時才知道其存在與大小的資料 程式能夠從堆中分配記憶體給這些元素 在用完之後,應該釋放掉這些記憶體。堆中所有的的東西都是匿名的 不能按名字直接訪問只能通過指標間接的訪問 棧 stack 為程式儲存的一塊記憶體區域,用來儲存狀態資料,例如 過程...
C C 記憶體分配
1 c c 記憶體分配 1 棧區 由編譯器自動分配和釋放,存放函式的引數值,區域性變數的值等。其操作方式類似於資料結構中的棧。2 堆區 一般由程式設計師分配和釋放,若程式設計師不釋放,程式結束時可能由os 注意它與資料結構中的堆是兩回事。3 全域性 靜態 資料區 全域性變數和靜態變數的儲存是放在一塊...