malloc函式 動態記憶體分配

2022-03-15 16:16:30 字數 3355 閱讀 4957

malloc 向系統申請分配指定size個位元組的記憶體空間。返回型別是 void* 型別。void* 表示未確定型別的

指標。c,c++規定,void* 型別可以

強制轉換

為任何其它型別的指標。

原型:extern void *malloc(unsigned int num_bytes);

標頭檔案:在tc2.0中可以用malloc.h或 alloc.h (注意:alloc.h 與 malloc.h 的內容是完全一致的),而在visual c++6.0中可以用malloc.h或者stdlib.h。

功能:分配長度為num_bytes位元組的記憶體塊

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

說明:關於該函式的原型,在舊的版本中malloc返回的是char型指標,新的ansic標準規定,該函式返回為void型指標,因此必要時要進行型別轉換。

名稱解釋:malloc的全稱是memory allocation,中文叫動態記憶體分配,當無法知道記憶體具體位置的時候,想要繫結真正的記憶體空間,就需要用到動態的分配記憶體。

相關函式:calloc、realloc、free、_alloca

void *malloc(size_t size);

備註:void* 表示未確定型別的指標

,void *可以指向任何型別的資料,更明確的說是指申請記憶體空間時還不知道使用者是用這段空間來儲存什麼型別的資料(比如是char還是int或者...)

從函式宣告上可以看出。malloc 和 new 至少有兩個不同: new 返回指定型別的指標

,並且可以自動計算所需要大小。比如:

int *p;

p = new int; //返回型別為int* 型別(整數型指標),分配大小為 sizeof(int);

或:int* parr;

parr = new int [100]; //返回型別為 int* 型別(整數型指標),分配大小為 sizeof(int) * 100;

而 malloc 則必須要由我們計算位元組數,並且在返回後強行轉換為實際型別的指標。

int* p;

p = (int *) malloc (sizeof(int)*128);//分配128個(可根據實際需要替換該數值)整型儲存單元,並將這128個連續的整型儲存單元的首位址儲存到指標變數p中

double *pd=(double *) malloc (sizeof(double)*12);//分配12個double型儲存單元,並將首位址儲存到指標變數pd中

第一、malloc 函式返回的是 void * 型別。對於c++,如果你寫成:p = malloc (sizeof(int)); 則程式無法通過編譯,報錯:「不能將 void* 賦值給 int * 型別變數」。所以必須通過 (int *) 來將強制轉換。而對於c,沒有這個要求,但為了使c程式更方便的移植到c++中來,建議養成強制轉換的習慣。

第二、函式的實參為 sizeof(int) ,用於指明乙個整型資料需要的大小。如果你寫成:

int* p = (int *) malloc (1);

**也能通過編譯,但事實上只分配了1個位元組大小的記憶體空間,當你往裡頭存入乙個整數,就會有3個位元組無家可歸,而直接「住進鄰居家」!造成的結果是後面的記憶體中原有資料內容被改寫。

在linux中可以有這樣:malloc(0),這是因為linux中malloc有乙個下限值16bytes,注意malloc(-1)是禁止的;

但是在某些系統中是不允許malloc(0)的。在規範的程式中我們有必要按照這樣的格式去使用malloc及free:

type *p;

if (null == (p = (type *)malloc(sizeof (type)))) /*請使用if來判斷,這是有必要的*/

... /*其它***/

free(p);

p = null; /***上這句*/

malloc 也可以達到 new 的效果,申請出一段連續的記憶體,方法無非是指定你所需要記憶體大小。

比如想分配100個int型別的空間:

int* p = (int *) malloc ( sizeof(int) * 100 ); //分配可以放得下100個整數的記憶體空間。

另外有一點不能直接看出的區別是,malloc 只管分配記憶體,並不能對所得的記憶體進行初始化,所以得到的一片新記憶體中,其值將是隨機的。

除了分配及最後釋放的方法不一樣以外,通過malloc或new得到指標,在其它操作上保持一致。

對其做乙個特例補充

char *ptr;

if ((ptr = (char *)malloc(0)) == null)

puts("got a null pointer");

else

puts("got a valid pointer");

此時得到的是got a valid pointer。把0賦給malloc能得到乙個合法的指標。

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

linux libc6採用的機制是在free的時候試圖整合相鄰的碎片,使其合併成為乙個較大的free空間。

例1:正常片段:

typedef struct data_type data;

data *bob;

bob = (data *) malloc( sizeof(data) );

if( bob != null ) else

free( bob );

bob = null;

記憶體洩漏例項:

#include

#include

#define max 100000000

int main(void)

return 0;

}例2:

#include "stdio.h" //

#include "malloc.h" //malloc()函式被藏在stdio.h裡面

int main(void) // 主函式程式的入口

動態記憶體分配 malloc 和free

1 通過查詢gcc的man手冊,我們可以看到malloc的函式原型 void malloc size t size 分配長度為size位元組的記憶體塊 1 返回值是void指標,void 表示未確定型別的指標,void 可以指向任何型別的資料,指標指向的型別是不確定的,這個指標在需要的時候可以被強制...

大名鼎鼎的malloc函式(動態記憶體分配)

原型 extern void malloc unsigned int num bytes 標頭檔案 在tc2.0中可以用malloc.h或 alloc.h 注意 alloc.h 與 malloc.h 的內容是完全一致的 而在visual c 6.0中可以用malloc.h或者stdlib.h。功能 ...

動態記憶體分配

在c 中建立乙個物件時,我們必須要為這個物件申請一塊記憶體,而且要用建構函式對這塊記憶體進行初始化。c 中的new和delete相對於c的庫函式malloc和free在這方面有很大的優勢,所以我們主要講的是運算子new和delete。當用new來建立乙個物件時,它會自動在堆裡為物件分配記憶體並且為這...