天天看點

alloca malloc calloc realloc,new差別聯系以及什麼時候用

C語言跟記憶體申請相關的函數主要有 alloca、calloc、malloc、free、realloc等.

    <1>alloca是向棧申請記憶體,是以無需釋放.

    <2>malloc配置設定的記憶體是位于堆中的,并且沒有初始化記憶體的内容,是以基本上malloc之後,調用函數memset來初始化這部分的記憶體空間.

    <3>calloc則将初始化這部分的記憶體,設定為0.

    <4>realloc則對malloc申請的記憶體進行大小的調整.

    <5>申請的記憶體最終需要通過函數free來釋放.

    當程式運作過程中malloc了,但是沒有free的話,會造成記憶體洩漏.一部分的記憶體沒有被使用,但是由于沒有free,是以系統認為這部分記憶體還在使用,造成不斷的向系統申請記憶體,使得系統可用記憶體不斷減少.但是記憶體洩漏僅僅指程式在運作時,程式退出時,OS将回收所有的資源.是以,适當的重起一下程式,有時候還是有點作用.

三個函數的申明分别是:

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

void* malloc(unsigned size);

void* calloc(size_t numElements, size_t sizeOfElement);

都在stdlib.h函數庫内

它們的傳回值都是請求系統配置設定的位址,如果請求失敗就傳回NULL

malloc用于申請一段新的位址,參數size為需要記憶體空間的長度,如:

char* p;

p=(char*)malloc(20);

calloc與malloc相似,參數sizeOfElement為申請位址的機關元素長度,numElements為元素個數,如:

char* p;

p=(char*)calloc(20,sizeof(char));

這個例子與上一個效果相同

realloc是給一個已經配置設定了位址的指針重新配置設定空間,參數ptr為原有的空間位址,newsize是重新申請的位址長度

如:

char* p;

p=(char*)malloc(sizeof(char)*20);

p=(char*)realloc(p,sizeof(char)*40);

注意,這裡的空間長度都是以位元組為機關。

C語言的标準記憶體配置設定函數:malloc,calloc,realloc,free等。

malloc與calloc的差別為1塊與n塊的差別:

malloc調用形式為(類型*)malloc(size):在記憶體的動态存儲區中配置設定一塊長度為“size”位元組的連續區域,傳回該區域的首位址。

calloc調用形式為(類型*)calloc(n,size):在記憶體的動态存儲區中配置設定n塊長度為“size”位元組的連續區域,傳回首位址。

realloc調用形式為(類型*)realloc(*ptr,size):将ptr記憶體大小增大到size。

free的調用形式為free(void*ptr):釋放ptr所指向的一塊記憶體空間。

C++中為new/delete函數。

如果調用成功,函數malloc()和函數calloc()都将傳回所配置設定的記憶體空間的首位址。

函數malloc()和函數calloc() 的主要差別是前者不能初始化所配置設定的記憶體空間,而後者能。如果由malloc()函數配置設定的記憶體空間原來沒有被使用過,則其中的每一位可能都是0;反之, 如果這部分記憶體曾經被配置設定過,則其中可能遺留有各種各樣的資料。也就是說,使用malloc()函數的程式開始時(記憶體空間還沒有被重新配置設定)能正常進行,但經過一段時間(記憶體空間還已經被重新配置設定)可能會出現問題。

函數calloc() 會将所配置設定的記憶體空間中的每一位都初始化為零,也就是說,如果你是為字元類型或整數類型的元素配置設定記憶體,那麽這些元素将保證會被初始化為0;如果你是為指針類型的元素配置設定記憶體,那麽這些元素通常會被初始化為空指針;如果你為實型資料配置設定記憶體,則這些元素會被初始化為浮點型的零。

malloc 向系統申請配置設定指定size個位元組的記憶體空間。傳回類型是 void* 類型。void* 表示未确定類型的指針。C,C++規定,void* 類型可以強制轉換為任何其它類型的指針。

從函數聲明上可以看出。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));

第一、malloc 函數傳回的是 void * 類型,如果你寫成:p = malloc (sizeof(int)); 則程式無法通過編譯,報錯:“不能将 void* 指派給 int * 類型變量”。是以必須通過 (int *) 來将強制轉換。

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

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

代碼也能通過編譯,但事實上隻配置設定了1個位元組大小的記憶體空間,當你往裡頭存入一個整數,就會有3個位元組無家可歸,而直接“住進鄰居家”!造成的結果是後面的記憶體中原有資料内容全部被清空。

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

比如想配置設定100個int類型的空間:

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

另外有一點不能直接看出的差別是,malloc隻管配置設定記憶體,并不能對所得的記憶體進行初始化,是以得到的一片新記憶體中,其值将是随機的。

轉自: http://blog.sina.com.cn/s/blog_7e9f39820100zr8l.html