1樓:檀香透窗櫺
malloc() 函式用來動態地分配記憶體空間,其原型為:void* malloc (size_t size);
說明:【引數說明】
size 為需要分配的記憶體空間的大小,以位元組(byte)計。
【函式說明】
malloc() 在堆區分配一塊指定大小的記憶體空間,用來存放資料。這塊記憶體空間在函式執行完成後不會被初始化,它們的值是未知的。如果希望在分配記憶體的同時進行初始化,請使用 calloc() 函式。
【返回值】
分配成功返回指向該記憶體的位址,失敗則返回 null。
操作:由於申請記憶體空間時可能有也可能沒有,所以需要自行判斷是否申請成功,再進行後續操作。
如果 size 的值為 0,那麼返回值會因標準庫實現的不同而不同,可能是 null,也可能不是,但返回的指標不應該再次被引用。
注意:函式的返回值型別是 void *,void 並不是說沒有返回值或者返回空指標,而是返回的指標型別未知。所以在使用 malloc() 時通常需要進行強制型別轉換,將 void 指標轉換成我們希望的型別,例如:
#include
typedef int listdata;
listdata *data; //儲存空間基址
data = ( listdata * ) malloc( 100 * sizeof ( listdata ) );
擴充套件資料
實現malloc的方法:
(1)資料結構
首先我們要確定所採用的資料結構。乙個簡單可行方案是將堆記憶體空間以塊的形式組織起來,每個塊由meta區和資料區組成,meta區記錄資料塊的元資訊(資料區大小、空閒標誌位、指標等等)。
資料區是真實分配的記憶體區域,並且資料區的第乙個位元組位址即為malloc返回的位址 。
(2)尋找合適的block
現在考慮如何在block鏈中查詢合適的block。一般來說有兩種查詢演算法:
first fit:從頭開始,使用第乙個資料區大小大於要求size的塊所謂此次分配的塊
best fit:從頭開始,遍歷所有塊,使用資料區大小大於size且差值最小的塊作為此次分配的塊
兩種方式各有千秋,best fit有較高的記憶體使用率(payload較高),而first fit具有較高的執行效率。這裡我們採用first fit演算法。
(3)開闢新的block
如果現有block都不能滿足size的要求,則需要在鍊表最後開闢乙個新的block。
(4)**block
first fit有乙個比較致命的缺點,就是可能會讓更小的size佔據很大的一塊block,此時,為了提高payload,應該在剩餘資料區足夠大的情況下,將其**為乙個新的block。
(5)malloc的實現
有了上面的**,我們就可以實現乙個簡單的malloc.注意首先我們要定義個block鍊表的頭first_block,初始化為null;另外,我們需要剩餘空間至少有block_size+8才執行**操作
由於我們需要malloc分配的資料區是按8位元組對齊,所以size不為8的倍數時,我們需要將size調整為大於size的最小的8的倍數。
2樓:guxuecan劍
c語言中malloc是動態記憶體分配函式。
函式原型:void *malloc(unsigned int num_bytes);
引數:num_bytes 是無符號整型,用於表示分配的位元組數;
返回值:如果分配成功則返回指向被分配記憶體的指標(此儲存區中的初始值不確定),否則返回空指標null。void* 表示未確定型別的指標,void *可以指向任何型別的資料,更明確的說是指申請記憶體空間時還不知道使用者是用這段空間來儲存什麼型別的資料(比如是char還是int或者其他型別);
標頭檔案:#include 或 #include (注意:alloc.h 與 malloc.h 的內容是完全一致的。)
功能:分配長度為num_bytes位元組的記憶體塊。
注意:當記憶體不再使用時,應使用free()函式將記憶體塊釋放。函式返回的指標一定要適當對齊,使其可以用於任何資料物件。
關於該函式的原型,在以前malloc返回的是char型指標,新的ansic標準規定,該函式返回為void型指標,因此必要時要進行型別轉換。
總結:malloc()函式其實就在記憶體中找一片指定大小的空間,然後將這個空間的首位址範圍給乙個指標變數,這裡的指標變數可以是乙個單獨的指標,也可以是乙個陣列的首位址,這要看malloc()函式中引數size的具體內容。
我們這裡malloc分配的記憶體空間在邏輯上連續的,而在物理上可以連續也可以不連續。對於我們程式設計師來說,我們關注的是邏輯上的連續,因為作業系統會幫我們安排記憶體分配,所以我們使用起來就可以當做是連續的。
程式例子:
# include
# include
int main(void)
int i = 5; //分配了4個位元組 靜態分配
int * p = (int *)malloc(sizeof(4));//指標變數p為靜態分配,malloc開闢的空間為動態分配
*p = 5; //*p 代表的就是乙個int變數,指標變數p表示是乙個以int型別的位址為內容的變數
free(p); //freep(p)表示把p所指向的記憶體給釋放掉,p本身的記憶體是靜態的,不能由程式設計師手動釋放
//p本身的記憶體只能在p變數所在的函式執行終止時由系統自動釋放
return 0;
擴充套件資料:
malloc在標準庫里的**實現:
#define null 0
#define memseze 8096
typedef double align;
typedef union header
struct s;
align a;
}header;
static header mem[memsize];
static header* memptr=null;
void* malloc(unsigned nbytes)
header *p,*newp;
unsigned nunits;
nunits=(nbytes+sizeof(header)-1)/sizeof(header)+1;
if(memptr==null)
memptr->s.next=memptr=mem;
memptr->s.usedsize=1;
memptr->s.freesize=memsize-1;
for(p=memptr;(p->s.next!=memptr) && (p->s.freesizes.next);
if(p->freesizenewp=p+p->s.usedsize;
newp->s.usedsize=nunits;
newp->s.freesize=p->s.freesize-nunits;
newp->s.next=p->s.next;
p->s.freesize=0;
p->s.next=newp;
memptr=newp;
return (void*)(newp+1);
void free(void* ap)
header *bp,*p,*prev;
bp=(header*)ap-1;
for(prev=memptr,p=memptr->s.next;
(p!=bp) && (p!=memptr);prev=p,p=p->next);
if(p!=bp) return;
prev->s.freesize+=p->s.usedsize+p->s.freesize;
prev->s.next=p->s.next;
memptr=prev;
c語言中malloc的意義:
malloc就是memory allocate動態分配記憶體,malloc的出現時為了彌補靜態記憶體分配的缺點,靜態分配記憶體有如下缺點:
1、比如說,傳統的一維陣列,如int a[5],使用傳統的一維陣列需要事先指定陣列的長度,而且陣列的長度必須是乙個常量(巨集定義的 常量)
2、傳統陣列(靜態分配),不能手動釋放,只能等待系統釋放,靜態分配的變數在該函式內執行的時候有效,當靜態分配的變數所在函式執行完之後,該記憶體會自動釋放。靜態分配的記憶體,是在棧中分配的,其實在c語言中的函式呼叫也是通過棧來實現的,棧這種資料結構的乙個特點就是(先進後出)。
所以,在呼叫函式的時候,都是先壓入棧中,然後,再從最上面的函式開始執行,最後,執行到main函式結束。動態分配通過malloc分配,是在堆中分配的,堆不是一種資料結構,它是一種排序方式,堆排序。
3、傳統陣列的長度一旦定義之後,就不能更改,比如說,如果我有乙個業務在這之前給分配的大小為100,但是,我現在由於業務數量的增長,原來的大小就無法滿足。
4、靜態分配不能跨函式呼叫,就是無法在另乙個函式中,來管理乙個函式中的記憶體。靜態分配,只在當前函式有效,當,靜態分配所在的函式執行完之後,該變數就不能被其他的函式所呼叫。
c語言中怎麼使用malloc函式?
3樓:程式小兵
malloc只是動態分配記憶體儲存空間。
void *malloc(long nbytes):該函式分配了nbytes個位元組,並返回了指向這塊記憶體的指標。如果分配失敗,則返回乙個空指標(null)
例如:char *ptr = null;
ptr = (char *)malloc(100 * sizeof(char));
就是這樣!當然,具體情況要具體分析以及具體解決。比如說,你定義了乙個指標,在乙個函式裡申請了一塊記憶體然後通過函式返回傳遞給這個指標,那麼也許釋放這塊記憶體這項工作就應該留給其他函式了
4樓:獨思有疑
先定義後使用
陣列int a[10];
變數int b;b=9;等
全都是書上的東西~!
C語言malloc函式如圖malloc前後的兩個型別說明符必須一致嗎?!為什麼
超可愛 不一定非要一致,但一般是一致的。malloc前面的型別是強制轉換型別,該型別的選取與被賦值的指標型別一致。例如 int p p int malloc sizeof int p為int型指標,所以要將分配的記憶體空間轉化成int型別,賦值給p。malloc後面的型別是為了給指標分配空間而計算記...
c語言中include是什麼,C語言中include是什麼
include 是c語言的關鍵字 c語言有自己的函式庫,你要是想要用函式庫裡的函式就必須把包含這些函式的檔案包含進來,這時就需要用include關鍵字了,舉個例子 include stdio.h中包含基本輸入輸出函式祝你好運!包含指令,比如要使用printf scanf gets等函式就需要包含st...
c語言中temp是什麼,C語言中temp是什麼
temp 是自己定義的。常常定義為起臨時作用的變數。比如有a,b兩個變數,現在交換他們的值,就再定義個temptemp a a bb temp 這樣就實現了交換兩個值。 一般只是用來定義區域性變數的,由於臨時使用,所以名字取的有點隨意. 天雲一號 在c語言中,temp沒有特別的含義,既不是關鍵字也不...