在程式的執行期間分配記憶體時,記憶體區域中的這個空間稱為堆(heap)。還有另乙個記憶體區域,稱為棧(stack),其中的空間分配給函式的引數和本地變數。在執行完該函式後,儲存引數和本地變數的記憶體空間就會釋放。堆中的記憶體是由程式設計師控制的。在分配堆上的記憶體時,由程式設計師跟蹤所分配的記憶體何時不再需要,並釋放這些空間,以便於以後重用它們。
使用動態記憶體很明顯的好處就是:不需要預先分配儲存空間且分配的空間可以根據程式的需要擴大或縮小,這樣可以有效的使用記憶體空間。
malloc和free
c函式庫中的malloc和free分別用於執行動態記憶體分配和釋放。
void *malloc ( size_t size );
void free ( void *pointer );
malloc的作用:在記憶體的動態儲存區中分配乙個長度為size的連續空間。其引數是乙個無符號整形數,返回值是乙個指向所分配的連續儲存域的起始位址的指標。還有一點必須注意的是,當函式未能成功分配儲存空間(如記憶體不足)就會返回乙個null指標。所以在呼叫該函式時應該檢測返回值是否為null,確保非空之後再使用非常重要。malloc所分配的記憶體是一塊連續的空間。同時,malloc實際分配的記憶體空間可能會比你請求的多一點,但是這個行為只是由編譯器定義的。malloc不知道使用者所請求的記憶體需要儲存的資料型別,所以malloc返回乙個void *的指標,它可以轉換為其它任何型別的指標。
由於記憶體區域總是有限的,不能不限制地分配下去,而且乙個程式要盡量節省資源,所以當所分配的記憶體區域不用時,就要釋放它,以便其它的變數或者程式使用。這時我們就要用到free函式。free的引數必須要麼是null,要麼是從malloc、relloc、calloc返回的值。作用是釋放之前返回的指標指向的記憶體空間,向free傳遞乙個null引數不會產生任何效果。
calloc和realloc與malloc的區別
calloc和realloc的原型如下:
void *calloc ( size_t num_elements, size_t element_size );
void *realloc (void *ptr, size_t new_size );
calloc和malloc 主要的區別在於前者在返回記憶體的指標之前將它初始化為0,另外它們請求數量的方式不同。calloc的引數包括所需元素的數量和每個元素的位元組,根據這些值可以計算出總共需要分配的記憶體空間。
realloc函式用於修改乙個原先已經分配的記憶體塊的大小,可以使一塊記憶體的擴大或縮小。當起始空間的位址為空,即ptr = null,則同malloc。當ptr非空:若nuw_size < size,即縮小ptr所指向的記憶體空間,該記憶體塊尾部的部分記憶體被拿掉,剩餘部分記憶體的原先內容依然保留;若nuw_size > size,即擴大ptr所指向的記憶體空間,如果原先的記憶體尾部有足夠的擴大空間,則直接在原先的記憶體塊尾部新增記憶體,如果原先的記憶體尾部空間不足,或原先的記憶體塊無法改變大小,realloc將重新分配另一塊nuw_size大小的記憶體,並把原先那塊記憶體的內容複製到新的記憶體塊上。因此,使用realloc後就應該改用realloc返回的新指標。
使用方法示例
int *ptr =null;
ptr = (int*)malloc(sizeof(int)*size);
if (*ptr == null)
上例中動態分配了size個整型儲存區域。動態分配記憶體的步驟可細分為:分配size個整型的連續儲存空間,並返回乙個指向其起始位址的整型指標把此整型指標位址賦給ptr, 檢測返回值是否為null。注意,型別轉換(int*)將函式返回的位址轉換成int型別的指標。這麼做是因為malloc()是一般用途的函式,可為任何型別的資料分配記憶體。sizeof是乙個運算子,它返回乙個size_t型別的無符號整數,該整數是儲存它的引數需要的位元組數。它把關鍵字如int或float等作為引數,返回儲存該型別的資料項所需的位元組數。它的引數也可以是變數或陣列名。把陣列名作為引數時,sizeof返回儲存整個陣列所需的位元組數。前乙個例子請求分配足以儲存size個int資料項的記憶體。以這種方式使用sizeof,可以根據不同的c編譯器為int型別的值自動調整所需的記憶體空間。
int *p1,*p2;
p1 = (int*)malloc(size * sizeof(int));
p2=p1;
……
free(p1); /*或者free(p2)*/
給free函式傳遞其它的值很可能造成宕機或其它災難性的後果。注意:這裡重要的是指標的值,而不是用來申請動態記憶體的指標本身。
malloc返回值賦給p1,又把p1的值賦給p2,所以此時p1,p2都可作為free函式的引數。malloc函式是對儲存區域進行分配的。 free函式是釋放已經不用的記憶體區域的。 所以由這兩個函式就可以實現對記憶體區域進行動態分配並進行簡單的管理了。
下面是使用動態分配的記憶體的基本規則:
●避免分配大量的小記憶體塊。分配堆上的記憶體有一些系統開銷,所以分配許多小的記憶體塊比分配幾個大記憶體塊的系統開銷大。
●僅在需要時分配記憶體。只要使用完堆上的記憶體塊,就釋放它。
●總是確保釋放已分配的記憶體。在編寫分配記憶體的**時,就要確定在**的什麼地方釋放記憶體。
●在釋放記憶體之前,確保不會無意中覆蓋堆上分配的記憶體的位址,否則程式就會出現記憶體洩漏。在迴圈中分配記憶體時,要特別小心。
參考部落格:
malloc與realloc的區別
ansi c說明了三個用於儲存空間動態分配的函式 1 malloc 分配指定位元組數的儲存區。此儲存區中的初始值不確定 2 calloc 為指定長度的物件,分配能容納其指定個數的儲存空間。該空間中的每一位 bit 都初始化為0 3 realloc 更改以前分配區的長度 增加或減少 當增加長度時,可能...
malloc與realloc的區別
ansi c說明了三個用於儲存空間動態分配的函式 1 malloc 分配指定位元組數的儲存區。此儲存區中的初始值不確定 2 calloc 為指定長度的物件,分配能容納其指定個數的儲存空間。該空間中的每一位 bit 都初始化為0 3 realloc 更改以前分配區的長度 增加或減少 當增加長度時,可能...
malloc函式與realloc函式
malloc函式與realloc函式 動態儲存必備 malloc函式 malloc函式簡介 原型 extern void malloc unsigned int num bytes 標頭檔案 include 或 include 注意 alloc.h 與 malloc.h 的內容是完全一致的。功能 分...