今日寫程序,突然想到一個問題,為什么有時候不要malloc,為什么有時候要呢!好好查資料才了解到一些原理。
函數原型:void
*
malloc
(unsigned
int
num_bytes); //分配長度為num_bytes字節的內存塊
返回值是void指針,void* 表示未確定類型的指針,void *可以指向任何類型的數據,更明確的說是指申請內存空間時還不知道用戶是用這段空間來存儲什么類型的數據(比如是char還是int或者其他數據類型),可以通過類型強制轉化轉化為其他任意類型指針。如果分配成功則返回指向被分配內存的指針(此存儲區中的初始值不確定),否則返回空指針NULL。
為什么要?何時要?
malloc()是動態內存分配函數,用來向系統請求分配內存空間。當無法知道內存具體的位置時,想要綁定真正的內存空間,就要用到malloc()函數。因為malloc只管分配內存空間,並不能對分配的空間進行初始化,所以申請到的內存中的值是隨機的,經常會使用memset()進行置0操作后再使用。
與其配套的是free(),當申請到的空間不再使用時,要用free()函數將內存空間釋放掉,這樣可以提高資源利用率,最重要的是----就是因為它可以申請內存空間,然后根據需要進行釋放,才被稱為“動態內存分配”!
malloc()函數實質體現在,它有一個可以將可用內存塊連接成一個長長的列表的鏈表,這個鏈表就是所謂的空閑鏈表。調用malloc()函數時,它沿着連接表尋找一個大到可以滿足用戶請求要求的連續的內存塊,然后將內存塊一分為二,一塊的大小與用戶請求的內存大小相等,另一塊就是剩下的內存塊。接下來,它將用戶申請的那塊傳遞給用戶,將另一塊返回到連接表上(如果另一塊有的話)。
調用free()函數的時候,它將用戶想要釋放的內存塊鏈接到空閑鏈上。我們可以想到,最后的空閑鏈鏈接的內存空間一小塊一塊的塊,如果這是用戶申請分配一個較大的內存空間,那么空閑鏈上可能沒有符合用戶要求的內存塊了,這個時候,malloc()函數請求延時,並開始在空閑鏈上翻箱倒櫃的檢查各內存塊,對他們進行整理,將相鄰的小內存塊合並成較大的內存塊。如果無法獲得符合用於要求的內存空間,那么malloc()函數就會返回NULL,因此,調用malloc()函數的時候,一定要判斷它的返回值是否為NULL。
如何使用?
int
*p;
p = (
int
*)
malloc
(
sizeof
(
int
) * 128);
//分配128個整型存儲單元,並將這128個連續的整型存儲單元的首地址存儲到指針變量p中
double
*pd = (
double
*)
malloc
(
sizeof
(
double
) * 12);
//
分配12個double型存儲單元,並將首地址存儲到指針變量pd中
#include <stdio.h>
#include <malloc.h>
#define MAX 1000000
int
main(
void
)
{
int
*a[MAX] = {NULL};
int
i;
for
(i=0;i<MAX;i++)
{
a[i]=(
int
*)
malloc
(MAX); //此處沒有判斷返回值
}
return
0;
}
#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, 此處返回條件判斷錯誤,應為:if(NULL == a)
{
perror
(
"malloc"
);
return
-1;
}
sprintf
(a,
"%s"
,
"HelloWorld\n"
);
//"HelloWorld\n"寫入a指向的地址
printf
(
"%s\n"
,a);
free
(a);
//釋放掉使用的內存地址
return
0;
}