C語言 malloc、calloc、realloc的區別,callocrealloc
三個函數的申明分別是:
void* malloc(unsigned size);
void* realloc(void* ptr, unsigned newsize);
void* calloc(size_t numElements, size_t sizeOfElement);
都在stdlib.h函數庫內,它們的返回值都是請求系統分配的地址,如果請求失敗就返回NULL.
(1)函數malloc()
在內存的動態存儲區中分配一塊長度為size字節的連續區域,參數size為需要內存空間的長度,返回該區域的首地址. (2)函數calloc()
與malloc相似,參數sizeOfElement為申請地址的單位元素長度,numElements為元素個數,即在內存中申請numElements*sizeOfElement字節大小的連續地址空間. (3)函數realloc()
給一個已經分配了地址的指針重新分配空間,參數ptr為原有的空間地址,newsize是重新申請的地址長度.區別:
(1)函數malloc不能初始化所分配的內存空間,而函數calloc能.如果由malloc()函數分配的內存空間原來沒有被使用過,則其中的每一位可能都是0;反之, 如果這部分內存曾經被分配過,則其中可能遺留有各種各樣的數據.也就是說,使用malloc()函數的程序開始時(內存空間還沒有被重新分配)能正常進行,但經過一段時間(內存空間還已經被重新分配)可能會出現問題.
(2)函數calloc() 會將所分配的內存空間中的每一位都初始化為零,也就是說,如果你是為字符類型或整數類型的元素分配內存,那麼這些元素將保證會被初始化為0;如果你是為指針類型的元素分配內存,那麼這些元素通常會被初始化為空指針;如果你為實型數據分配內存,則這些元素會被初始化為浮點型的零.
(3)函數malloc向系統申請分配指定size個字節的內存空間.返回類型是 void*類型.void*表示未確定類型的指針.C,C++規定,void* 類型可以強制轉換為任何其它類型的指針.
(4)realloc可以對給定的指針所指的空間進行擴大或者縮小,無論是擴張或是縮小,原有內存的中內容將保持不變.當然,對於縮小,則被縮小的那一部分的內容會丟失.realloc並不保證調整後的內存空間和原來的內存空間保持同一內存地址.相反,realloc返回的指針很可能指向一個新的地址.
(5)realloc是從堆上分配內存的.當擴大一塊內存空間時,realloc()試圖直接從堆上現存的數據後面的那些字節中獲得附加的字節,如果能夠滿足,自然天下太平;如果數據後面的字節不夠,問題就出來了,那麼就使用堆上第一個有足夠大小的自由塊,現存的數據然後就被拷貝至新的位置,而老塊則放回到堆上.這句話傳遞的一個重要的信息就是數據可能被移動.
#include <stdio.h>
#include <malloc.h>
int main(int argc, char* argv[])
{
char *p,*q;
p = (char *)malloc(10);
q = p;
p = (char *)realloc(p,10);
printf("p=0x%x/n",p);
printf("q=0x%x/n",q);
return 0;
}
輸出結果:realloc後,內存地址不變
p=0x431a70
q=0x431a70
例2:
#include <stdio.h>
#include <malloc.h>
int main(int argc, char* argv[])
{
char *p,*q;
p = (char *)malloc(10);
q = p;
p = (char *)realloc(p,1000);
printf("p=0x%x/n",p);
printf("q=0x%x/n",q);
return 0;
}
輸出結果:realloc後,內存地址發生了變化
p=0x351c0
q=0x431a70