malloc/calloc/realloc之間區別詳解

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.使用方法:

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類型指針。

3. malloc/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.calloc會對申請空間初始化,並且初始化爲0,而其他兩個不會。
3.malloc申請的空間必須使用memset初始化
4.realloc是對已經存在的空間進行調整,當第一個參數傳入NULL的時候和malloc一樣
調整分爲兩種情況:

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

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

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

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

擴展閱讀:

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

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