1. 程式人生 > 實用技巧 >malloc、calloc、ralloc

malloc、calloc、ralloc

轉載自:https://blog.csdn.net/qq_38810767/article/details/85265541

malloc memory allocate;calloc clear allocate; ralloc re-allocate

1. malloc/calloc/realloc和free介紹:

1. malloc函式

malloc函式可以從堆上獲得指定位元組的記憶體空間,其函式宣告如下:

void * malloc(int n);

引數釋義:
n:申請空間大小(單個型別大小*總個數)

函式詳述:
其中,形參n為要求分配的位元組數。如果函式執行成功,malloc返回獲得記憶體空間的首地址;如果函式執行失敗,那麼返回值為NULL。由於malloc函式值的型別為void型指標,因此,可以將其值型別轉換後賦給任意型別指標,這樣就可以通過操作該型別指標來操作從堆上獲得的記憶體空間。
需要注意的是,malloc函式分配得到的記憶體空間是未初始化的。
注意:通過malloc函式得到的堆記憶體必須使用memset函式來初始化。

2. calloc函式

calloc函式的功能與malloc函式的功能相似,都是從堆分配記憶體。其函式宣告如下:

void *calloc(int n,int size);
引數釋義:
size:單個型別大小
n:申請的個數
注意:最後申請空間大小為: n和size相乘

函式詳述:
函式返回值為void型指標。如果執行成功,函式從堆上獲得size * n的位元組空間,並返回該空間的首地址。如果執行失敗,函式返回NULL。該函式與malloc函式的一個顯著不同時是,calloc函式得到的記憶體空間是經過初始化的,其內容全為0。calloc函式適合為陣列申請空間,可以將size設定為陣列元素的空間長度,將n設定為陣列的容量。

3. realloc函式

realloc函式的功能比malloc函式和calloc函式的功能更為豐富,可以實現記憶體分配和記憶體釋放的功能,其函式宣告如下:

void * realloc(void * p,int n);

引數釋義:
p:堆上已經存在空間的地址
n:空間的大小

函式詳述:
其中,指標p必須為指向堆記憶體空間的指標,即由malloc函式、calloc函式或realloc函式分配空間的指標。realloc函式將指標p指向的記憶體塊的大小改變為n位元組。如果n小於或等於p之前指向的空間大小,那麼。保持原有狀態不變。如果n大於原來p之前指向的空間大小,那麼,系統將重新為p從堆上分配一塊大小為n的記憶體空間,同時,將原來指向空間的內容依次複製到新的記憶體空間上,p之前指向的空間被釋放。relloc函式分配的空間也是未初始化的。

注意:使用malloc函式,calloc函式和realloc函式分配的記憶體空間都要使用free函式或指標引數為NULL的realloc函式來釋放。

2.2使用方法:

1、malloc()

標頭檔案:stdlib.h

宣告:void * malloc(int n);

含義:在堆上,分配n個位元組,並返回void指標型別。

返回值:分配記憶體成功,返回分配的堆上儲存空間的首地址;否則,返回NULL

初始化:未初始化

2、calloc()

標頭檔案:stdlib.h

宣告:void *calloc(int n, int size);

含義:在堆上,分配nsize個位元組,並初始化為0,返回void型別

返回值:同malloc() 函式

初始化:已初始化

3、recalloc()

標頭檔案:stdlib.h

宣告:void * realloc(void * p,int n);

含義:重新分配堆上的void指標p所指的空間為n個位元組,同時會複製原有內容到新分配的堆上儲存空間。注意,若原來的void指標p在堆上的空間不大於n個位元組,則保持不變。

返回值:同malloc() 函式

初始化:未初始化
4、free()

標頭檔案:stdlib.h

宣告:void free (void * p);

含義:釋放void指標p所指的堆上的空間。

返回值:無

5、memset()

標頭檔案:string.h

宣告:void * memset (void * p, int c, int n) ;

含義:對於void指標p為首地址的n個位元組,將其中的每個位元組設定為c。

返回值:返回指向儲存區域 p 的void型別指標。

2.3malloc/calloc/realloc區別總結

相同點:
1.都是從堆上申請空間
2.都需要對返回值判空
3.都需要使用者free釋放
4.返回值型別相同(void*)
5.都需要型別轉化
6.底層實現上是一樣的,都需要開闢多餘的空間,用來維護申請的空間

可以輸入以下程式碼觀測記憶體:

#include <stdio.h>
#include <malloc.h>
int main(){
int *p= (int *)malloc(sizeof(int )*10);
return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

不同點:
1.函式名字不同和引數型別不同。
2.calloc會對申請空間初始化,並且初始化為0,而其他兩個不會。
3.malloc申請的空間必須使用memset初始化
4.realloc是對已經存在的空間進行調整,當第一個引數傳入NULL的時候和malloc一樣
調整分為兩種情況:

a:調整的空間比原有空間大:

1.大了一點:多出來的空間小於小於下面空閒的空間;
做法:
1.直接延伸申請空間
2.返回原空間首地址**

2.大了很多:多出來的空間,大於下面空閒空間
做法:
1.重新開闢新空間
2.將舊空間的內容拷貝到新空間中
3.釋放舊空間
4.返回新空間的首地址

b.調整的空間比原有空間小:
做法:
1.將原空間縮小
2 .返回舊空間首地址

擴充套件閱讀:
.alloca函式:

還有一個函式也值得一提,這就是alloca。其呼叫序列與malloc相同,但是它是在當前函式的棧幀上
分配儲存空間,而不是在堆中。其優點是:當函式返回時,自動釋放它所使用的棧幀,所以不必再為釋
放空間而費心。其缺點是:某些系統在函式已被呼叫後不能增加棧幀長度,於是也就不能支援alloca函式。
儘管如此,很多軟體包還是使用alloca函式,也有很多系統支援它。