(一)malloc
extern void *mallic(unsigned int num_bytes);
頭文件:#include #include
功能
請求系統動態分配num_bytes個字節的空間,如果分配成功則返回第一個字節的地址,並且可以進行強制類型轉換,告訴系統分配空間中存儲的是那種類型的數據。否則返回空指針NULL。
注意:當內存不再使用時,應使用free()函數將內存塊釋放。
(二)ralloc
函數原型:
extern void *realloc(void *mem_address,unsigned int newsize);
頭文件:#include
功能
先判斷當前的指針是否有足夠的連續空間,如果有,擴大mem_address指向的地址,並且將mem_address返回,如果空間不夠, 先按照newsize指定的大小分配空間,將原有數據從頭到尾拷貝到新分配的內存區域,而后釋放原來mem_address所指內存區域(注意:原來指針是自動釋放,不需要使用free),同時返回新分配的內存區域的首地址。即重新分配存儲器塊的地址。
返回值
如果重新分配成功則返回指向被分配內存的指針,否則返回空指針NULL。
注意
當內存不再使用時,應使用free()函數將內存塊釋放。
使用總結:
1. ralloc失敗的時候,返回NULL
2. ralloc失敗的時候,原來的內存不改變,不會釋放也不會移動
3. 假如原來的內存后面還有足夠多剩余內存的話,ralloc的內存=原來的內存+剩余內存,ralloc還是返回原來內存的地址; 假如原來的內存后面沒有足夠多剩余內存的話,ralloc將申請新的內存,然后把原來的內存數據拷貝到新內存里,原來的內存將被free掉,ralloc返回新內存的地址
4. 如果size為0,效果等同於free()。
5. 傳遞給realloc的指針必須是先前通過malloc(), calloc(),或realloc()分配的.
6. 傳遞給realloc的指針可以為空,等同於malloc。
(三) calloc
函數原型:void *calloc(size_t n, size_t size)
頭文件:#include
#include
功能:
在內存的動態分配區中分配n個長度為size的連續空間,函數返回一個指向分配起始地址的指針;如果分配不成功,
返回NULL。
在了解了每個函數的基本功能后,說下他們之間的區別
(1)函數malloc不能初始化所分配的內存空間,也就是說malloc分配好空間后要對所分配的空間進行清理。而函數calloc() 會將所分配的內存空間中的每一位都初始化為零,也就是說,如果你是為字符類型或整數類型的元素分配內存,那么這些元素將保證會被初始化為0;如果你是為指針類型的元素分配內存,那么這些元素通常會被初始化為空指針;
(2)函數malloc向系統申請分配指定size個字節的內存空間.返回類型是 void*類型.void*表示未確定類型的指針. void* 類型可以強制轉換為任何其它類型的指針.
實現原理:malloc、calloc函數的實質體現在,它有一個將可用的內存連接為一個長長的鏈表(即所謂的空閑鏈表)。調用malloc函數時,它沿連接表尋找一個大到足以滿足用戶請求所需要的內存塊,然后將該內存塊一分為二(一塊的大小與用戶申請的大小一樣,另一塊就是剩下的字節),接下來,將分配給用戶的那塊內存傳給用戶,並將剩下的那塊(如果有的話)返回到鏈表上,調用free函數 時,它將用戶釋放的內存塊連接到空鏈上,到最后,空閑鏈表會被切成很多的小內存片段,如果這時用戶申請一個大的內存片段,那么空閑鏈上可能沒有可能滿足用戶要求的片段了,於是malloc函數請求延時,並開始在空間中翻箱倒櫃的檢查內存片段,對它們進行整理,並將相鄰的小空閑塊合成較大的內存塊realloc是從堆空間上分配內存,當擴大一塊內存空間時,realloc試圖直接從現存的數據后面的哪些字節中獲得附加的字節,如果能夠滿足,自然天下太平,那么如果后面的字節不夠,問題就來了,那么就使用堆上第一個足夠滿足要求的自由空間塊,現存的數據然后就被拷貝到新的位置上,而老塊則放回堆空間,這句話傳遞的一個很重要的信息就是數據可能被移。