C語言-malloc

malloc函數

編輯 鎖定 同義詞 malloc通常指malloc函數c++

 
malloc函數是一種分配長度爲num_bytes字節的內存塊的函數,能夠向系統申請分配指定size個字節的內存空間。malloc的全稱是memory allocation,中文叫動態內存分配,當沒法知道內存具體位置的時候,想要綁定真正的內存空間,就須要用到動態的分配內存。
返回類型是 void* 類型。void* 表示未肯定類型的指針。C,C++規定,void* 類型能夠經過類型轉換強制轉換爲任何其它類型的指針。
 
中文名
動態內存分配
外文名
memory allocation
簡    稱
malloc
原    型
extern void *malloc
頭文件
stdlib.h

malloc函數函數定義

編輯

malloc函數原型

?
1
extern  void  * malloc (unsigned  int  num_bytes);

malloc函數頭文件

?
1
2
3
#include <stdlib.h>
或者
#include <malloc.h>

malloc函數函數聲明

?
1
void  * malloc ( size_t  size);
備註:void* 表示未肯定類型的 指針 ,void *能夠指向任何類型的數據,更明確的說是指申請內存空間時還不知道用戶是用這段空間來存儲什麼類型的數據(好比是char仍是 int 或者其餘數據類型)。

malloc函數返回值

若是分配成功則返回指向被分配內存的 指針(此存儲區中的初始值不肯定),不然返回空指針 NULL。當內存再也不使用時,應使用free()函數將內存塊釋放。函數返回的指針必定要適當對齊,使其能夠用於任何 數據對象

malloc函數說明

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

malloc函數相關函數

malloc函數與new的區別

編輯
從本質上來講,malloc( Linux上具體實現能夠參考man malloc,glibc經過brk()&mmap()實現)是libc裏面實現的一個函數,若是在source code中沒有直接或者間接include過stdlib.h,那麼gcc就會報出error:‘malloc’ was not declared in this scope。若是生成了目標文件(假定動態連接malloc),若是運行平臺上沒有libc(Linux平臺,手動指定LD_LIBRARY_PATH到一個空目錄便可),或者libc中沒有malloc函數,那麼會在運行時(Run-time)出錯。new則否則,是c++的關鍵字,它自己不是函數。new不依賴於頭文件, c++編譯器就能夠把new編譯成目標代碼(g++4.6.3會向目標中插入_Znwm這個函數,另外,編譯器還會根據參數的類型,插入相應的構造函數)。
在使用上,malloc 和 new 至少有兩個不一樣: new 返回指定類型的 指針,而且能夠自動計算所須要大小。好比:
?
1
2
3
int  *p;
p =  new  int ;
//返回類型爲int *類型(整數型指針),分配大小爲sizeof(int);
或:
?
1
2
3
int  *parr;
parr =  new  int [100];
//返回類型爲int *類型(整數型指針),分配大小爲sizeof(int) * 100;
而 malloc 則必需要由咱們計算字節數,而且在返回後強行轉換爲實際類型的 指針
?
1
2
3
4
5
6
7
int  *p;
p = ( int *) malloc ( sizeof ( int ) * 128);
//分配128個(可根據實際須要替換該數值)整型存儲單元,
//並將這128個連續的整型存儲單元的首地址存儲到指針變量p中
double  *pd = ( double *) malloc ( sizeof ( double ) * 12);
//分配12個double型存儲單元,
//並將首地址存儲到指針變量pd中
第1、malloc 函數返回的是 void * 類型。
對於C++,若是你寫成:p = malloc (sizeof(int)); 則程序沒法經過編譯,報錯:「不能將 void* 賦值給 int * 類型變量」。
因此必須經過 (int *) 來將 強制轉換。而對於C,沒有這個要求,但爲了使C程序更方便的移植到C++中來,建議養成強制轉換的習慣。
第2、函數的 實參爲 sizeof(int) ,用於指明一個 整型數據須要的大小。
在Linux中能夠有這樣:malloc(0),這是由於Linux中malloc有一個下限值16Bytes,注意malloc(-1)是禁止的;可是在某些系統中是不容許malloc(0)的。
在規範的程序中咱們有必要按照這樣的格式去使用malloc及free:
?
1
2
3
4
5
6
7
8
9
10
type *p;
if (NULL == (p = (type*) malloc ( sizeof (type))))
/*請使用if來判斷,這是有必要的*/
{
     perror ( "error..." );
     exit (1);
}
... /*其它代碼*/
free (p);
p = NULL; /*請加上這句*/
malloc 也能夠達到 new [] 的效果,申請出一段連續的內存,方法無非是指定你所須要內存大小。
好比想分配100個int類型的空間:
?
1
2
int  *p = ( int *) malloc ( sizeof ( int ) * 100);
//分配能夠放得下100個整數的內存空間。
另外有一點不能直接看出的區別是,malloc 只管分配內存,並不能對所得的內存進行初始化,因此獲得的一片新內存中,其值將是隨機的。
除了分配及最後釋放的方法不同之外,經過malloc或new獲得 指針,在其它操做上保持一致。
對其作一個特例補充
?
1
2
3
4
5
char  *ptr;
if ((ptr = ( char *) malloc (0)) == NULL)
     puts ( "Gotanullpointer" );
else
     puts ( "Gotavalidpointer" );
此時獲得的是Got a valid pointer。把0賦給malloc能獲得一個合法的 指針

malloc函數工做機制

編輯
malloc函數的實質體如今,它有一個將可用的內存塊鏈接爲一個長長的列表的所謂空閒 鏈表。調用malloc函數時,它沿 鏈接表尋找一個大到足以知足用戶請求所須要的內存塊。而後,將該內存塊一分爲二(一塊的大小與用戶請求的大小相等,另外一塊的大小就是剩下的字節)。接下來,將分配給用戶的那塊內存傳給用戶,並將剩下的那塊(若是有的話)返回到鏈接表上。調用free函數時,它將用戶釋放的內存塊鏈接到空閒鏈上。到最後,空閒鏈會被切成不少的小內存片斷,若是這時用戶申請一個大的內存片斷,那麼空閒鏈上可能沒有能夠知足用戶要求的片斷了。因而,malloc函數請求延時,並開始在空閒鏈上翻箱倒櫃地檢查各內存片斷,對它們進行整理,將相鄰的小空閒塊合併成較大的內存塊。若是沒法得到符合要求的內存塊,malloc函數會返回NULL 指針,所以在調用malloc動態申請內存塊時,必定要進行返回值的判斷。
Linux Libc6採用的機制是在free的時候試圖整合相鄰的碎片,使其合併成爲一個較大的free空間。

malloc函數程序示例

編輯

malloc函數正常程序

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
typedef  struct  data_type{
 
 
     int  age;
     
 
     char  name[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;

malloc函數內存泄漏實例

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
例1:
#include <stdio.h>
#include <malloc.h>
#define MAX 100000000
 
int  main( void )
{
     int  *a[MAX] = {NULL};
     int  i;
     for (i=0;i<MAX;i++)
     {
     a[i]=( int *) malloc (MAX);
     }
     return  0;
}
例2:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include "stdio.h"
 
#include "malloc.h"//malloc()函數被包含在malloc.h裏面
 
 
int  main( 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); //釋放掉使用的內存地址
 
     return  0; //例2有無內存泄露?
  
}
 
注:例1:對 malloc 申請以後沒有檢測返回值;例2:檢測 malloc 返回值條件有誤(例2是對的吧?)。
相關文章
相關標籤/搜索