malloc

malloc

malloc是一種程式語言。是向系統申請分配指定size個位元組的記憶體空間。返回類型是void*類型。void*表示未確定類型的指針。C,C++規定,void*類型可以強制轉換為任何其它類型的指針。

基本信息

定義

原型

malloc操作示意圖malloc操作示意圖
externvoid*malloc(unsignedintnum_bytes);

功能

分配長度為num_bytes位元組的記憶體

返回值

如果分配成功則返回指向被分配記憶體的指針(此存儲區中的初始值不確定),否則返回空指針NULL。當記憶體不再使用時,應使用free()函式將記憶體塊釋放。函式返回的指針一定要適當對齊,使其可以用於任何數據對象。

說明

關於該函式的原型,在以前malloc返回的是char型指針,新的ANSIC標準規定,該函式返回為void型指針,因此必要時要進行類型轉換。

名稱解釋

malloc的全稱是memoryallocation,中文叫動態記憶體分配,當無法知道記憶體具體位置的時候,想要綁定真正的記憶體空間,就需要用到動態的分配記憶體。

相關函式

callocreallocfreealloca

函式聲明

全名

void*malloc(size_tsize);

備註

void*表示未確定類型的指針,void*可以指向任何類型的數據,更明確的說是指申請記憶體空間時還不知道用戶是用這段空間來存儲什麼類型的數據(比如是char還是int或者……)

與new的區別

mallocmalloc
new則不然,是c++的關鍵字,它本身不是函式。new不依賴於頭檔案,c++編譯器就可以把new編譯成目標代碼(g++4.6.3會向目標中插入_Znwm這個函式,另外,編譯器還會根據參數的類型,插入相應的構造函式)。

在使用上,malloc和new至少有兩個不同:new返回指定類型的指針,並且可以自動計算所需要大小。
而malloc則必須要由我們計算位元組數,並且在返回後強行轉換為實際類型的指針。
第一、malloc函式返回的是void*類型。對於C++,如果你寫成:p=malloc(sizeof(int));則程式無法通過編譯,報錯:“不能將void*賦值給int*類型變數”。所以必須通過(int*)來將強制轉換。而對於C,沒有這個要求,但為了使C程式更方便的移植到C++中來,建議養成強制轉換的習慣。
第二、函式的實參為sizeof(int),用於指明一個整型數據需要的大小。
在Linux中可以有這樣:malloc(0),這是因為Linux中malloc有一個下限值16Bytes,注意malloc(-1)是禁止的;
但是在某些系統中是不允許malloc(0)的。在規範的程式中我們有必要按照這樣的格式去使用malloc及free:
malloc也可以達到new[]的效果,申請出一段連續的記憶體,方法無非是指定你所需要記憶體大小。
比如想分配100個int類型的空間:
另外有一點不能直接看出的區別是,malloc只管分配記憶體,並不能對所得的記憶體進行初始化,所以得到的一片新記憶體中,其值將是隨機的。
除了分配及最後釋放的方法不一樣以外,通過malloc或new得到指針,在其它操作上保持一致。
對其做一個特例補充
此時得到的是Gotavalidpointer。把0賦給malloc能得到一個合法的指針。

工作機制

malloc函式的實質體現在,它有一個將可用的記憶體塊連線為一個長長的列表的所謂空閒鍊表。調用malloc函式時,它沿連線表尋找一個大到足以滿足用戶請求所需要的記憶體塊。然後,將該記憶體塊一分為二(一塊的大小與用戶請求的大小相等,另一塊的大小就是剩下的位元組)。接下來,將分配給用戶的那塊記憶體傳給用戶,並將剩下的那塊(如果有的話)返回到連線表上。調用free函式時,它將用戶釋放的記憶體塊連線到空閒鏈上。到最後,空閒鏈會被切成很多的小記憶體片段,如果這時用戶申請一個大的記憶體片段,那么空閒鏈上可能沒有可以滿足用戶要求的片段了。於是,malloc函式請求延時,並開始在空閒鏈上翻箱倒櫃地檢查各記憶體片段,對它們進行整理,將相鄰的小空閒塊合併成較大的記憶體塊。如果無法獲得符合要求的記憶體塊,malloc函式會返回NULL指針,因此在調用malloc動態申請記憶體塊時,一定要進行返回值的判斷。
LinuxLibc6採用的機制是在free的時候試圖整合相鄰的碎片,使其合併成為一個較大的free空間。

程式示例

正常程式

typedefstructdata_type{
intage;
charname[20];
}data;
data*bob=NULL;
bob=(data*)malloc(sizeof(data));
if(bob!=NULL)
{
bob->age=22;
strcpy(bob->name,"Robert");
printf("%sis%dyearsold\n",bob->name,bob->age);
}
else
{
printf("mallocerror!\n");
exit(-1);
}
free(bob);
bob=NULL;

記憶體泄漏

例1:
#include<stdio.h>
#include<malloc.h>
#defineMAX100000000
intmain(void)
{
int*a[MAX]={NULL};
inti;
for(i=0;i<MAX;i++){
a[i]=(int*)malloc(MAX);
}
return0;
}

例2:
#include"stdio.h"
#include"malloc.h"//malloc()函式被包含在malloc.h裡面
intmain(void)
{
char*a=NULL;//聲明一個指向a的char*類型的指針
a=(char*)malloc(100*sizeof(char));//使用malloc分配記憶體的首地址,然後賦值給a
if(!a)//如果malloc失敗,可以得到一些log
{
perror("malloc");
return-1;
}
sprintf(a,"%s","HelloWorld\n");//"HelloWorld\n"寫入a指向的地址
printf("%s\n",a);//輸出用戶輸入的數據
free(a);//釋放掉使用的記憶體地址
return0;//例2有無記憶體泄露
}

例1:
對malloc申請之後沒有檢測返回值;
例2:
檢測malloc返回值條件有誤。

相關詞條

相關搜尋

熱門詞條

聯絡我們