malloc realloc calloc 的區別和聯繫 .

ANSI C說明了三個用於存儲空間動態分配的函數
(1) malloc 分配指定字節數的存儲區。此存儲區中的初始值不確定
(2) calloc 爲指定長度的對象,分配能容納其指定個數的存儲空間。該空間中的每一位(bit)都初始化爲0
(3) realloc 更改以前分配區的長度(增加或減少)。當增加長度時,可能需將以前分配區的內容移到另一個足夠大的區域,而新增區域內的初始值則不確定

四個函數的聲明分別是:

void* realloc(void* ptr, unsigned newsize);

void* malloc(unsigned size);

void* calloc(size_t nelem, size_t elsize);

free(q);                       //其中q爲已經分配的塊;

 malloc與calloc的區別爲1塊與n塊的區別:malloc調用形式爲(類型*)malloc(size):在內存的動態存儲區中分配一塊長度爲"size"字節的連續區域,返回該區域的首地址。

 calloc調用形式爲(類型*)calloc(n,size):在內存的動態存儲區中分配n塊長度爲"size"字節的連續區域,返回首地址。

realloc 不能保證重新分配後的內存空間和原來的內存空間指在同一內存地址, 它返回的指針很可能指向一個新的地址。
所以,在代碼中,必須把realloc返回的值,重新賦給 p 如:
p = (char *) realloc (p, old_size + new_size);
甚至,你可以傳一個空指針(0)給 realloc ,則此時realloc 作用完全相當於malloc。
int* p = (char *) realloc (0,old_size + new_size); //全新分配一個內存空間,作用完全等同於以下這行: int* p = (char *) malloc(old_size + new_size);
calloc(len, size)與malloc相似,參數len爲申請地址的單位元素長度,size爲元素個數,如:
char* p;
p=(char*)calloc(sizeof(char),1000);

對realloc的詳細語法說明:

void *realloc( void *memblock, size_t size );
一、如果memblock = 0, size != 0,表示爲空指針分配空間,同malloc(memblock, size)
二、如果memblock != 0, size = 0,表示將已分配的空間釋放,同free(memblock)
三、如果memblock != 0, size != 0,表示將已分配的空間重新分配,
1。如果size < memblock已分配內存大小,則將memblock的後部分切除,返回指針和memblock相等。
2。如果size > memblock已分配內存大小,
a)並且memblock大小和其後的自由內存總和大於等於size,則分配size大小的內存,返回指針和memblock相等。
b)如果memblock大小和其後的自由內存總和小於size,則在其他地方分配size大小的內存,返回指針和memblock不相等。如果其他地方也沒有足夠空間分配內存,則返回指針NULL。  

分配函數時再分配 realloc()   

使我們可以增、減以前分配區的長度(最常見的用法是增加該區)。
如果先分配一個可容納長度爲512的數組的空間,並在運行時填充它,但又發現空間不夠,則可調用realloc擴充該存儲空間。
如果在該存儲區後有足夠的空間可供擴充,則可在原存儲區位置上向高地址方向擴充,並返回傳送給它的同樣的指針值。
如果在原存儲區後沒有足夠的空間,則realloc分配另一個足夠大的存儲區,將現存的5 1 2個元素數組的內容複製到新分配的存儲區。
因爲這種存儲區可能會移動位置,所以不應當使用任何指針指在該區中。
 注意,realloc的最後一個參數是存儲區的newsize(新長度),不是新、舊長度之差。作爲一個特例,若ptr是一個空指針,則realloc的功能與malloc相同,用於分配一個指定長度newsize的存儲區。
這些分配例程通常通過sbrk(2)系統調用實現。該系統調用擴充(或縮小)進程的堆。雖然sbrk可以擴充或縮小一個進程的存儲空間,但是大多數 malloc和free的實現都不減小進程的存儲空間。釋放的空間可供以後再分配,但將它們保持在malloc池中而不返回給內核。
應當注意的是,大多數實現所分配的存儲空間比所要求的要稍大一些,額外的空間用來記錄管理信息——分配塊的長度,指向下一個分配塊的指針等等。這就意味着如果寫過一個已分配區的尾端,則會改寫後一塊的管理信息。這種類型的錯誤是災難性的,但是因爲這種錯誤不會很快就暴露出來,所以也就很難發現。
將指向分配塊的指針向後移動也可能會改寫本塊的管理信息。其他可能產生的致命性的錯誤是:釋放一個已經釋放了的塊;調用free時所用的指針不是三個 alloc函數的返回值等。因爲存儲器分配出錯很難跟蹤,所以某些系統提供了這些函數的另一種實現方法。每次調用這三個分配函數中的任意一個或free時都進行附加的出錯檢驗。在調用連接編輯程序時指定一個專用庫,則在程序中就可使用這種版本的函數。此外還有公共可用的資源(例如由4.3+BSD所提供的),在對其進行編譯時使用一個特殊標誌就會使附加的運行時間檢查生效。
因爲存儲空間分配程序的操作對某些應用程序的運行時間性能非常重要,所以某些系統提供了附加能力。例如,SVR4提供了名爲mallopt的函數,它使進程可以設置一些變量,並用它們來控制存儲空間分配程序的操作。還可使用另一個名爲mallinfo的函數,以對存儲空間分配程序的操作進行統計。請查看所使用系統的malloc(3)手冊頁,弄清楚這些功能是否可用。
alloca函數
還有一個函數也值得一提,這就是alloca。其調用序列與malloc相同,但是它是在當前函數的棧幀上分配存儲空間,而不是在堆中。其優點是:當函數返回時,自動釋放它所使用的棧幀,所以不必再爲釋放空間而費心。其缺點是:某些系統在函數已被調用後不能增加棧幀長度,於是也就不能支持alloca 函數。儘管如此,很多軟件包還是使用alloca函數,也有很多系統支持它。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章