天天看點

#C++基礎# 記憶體配置設定函數:malloc,calloc,realloc,_alloca, new, free, deletemalloc:calloc:realloc:new/new[]freedelete/delete[]

malloc:

void *malloc(size_t size);
           
  • 功能:在堆區申請空間長度為size位元組連續的記憶體塊。
  • 參數:size--申請空間長度位元組大小
  • 傳回值:如果配置設定成功則傳回指向被配置設定記憶體的指針(此存儲區中的初始值不确定)即申請空間的首位址,否則傳回空指針NULL。當記憶體不再使用時,應使用free()函數将記憶體塊釋放。函數傳回的指針一定要适當對齊,使其可以用于任何資料對象。
  • 注意:void* 表示未确定類型的指針,更明确的說是指申請記憶體空間時還不知道使用者是用這段空間來存儲什麼類型的資料(比如是char還是int或者...)
  • 工作機制:malloc函數的實質展現在,它有一個将可用的記憶體塊連接配接為一個長長的清單的所謂空閑連結清單。調用malloc函數時,它沿連接配接表尋找一個大到足以滿足使用者請求所需要的記憶體塊。然後,将該記憶體塊一分為二(一塊的大小與使用者請求的大小相等,另一塊的大小就是剩下的位元組)。接下來,将配置設定給使用者的那塊記憶體傳給使用者,并将剩下的那塊(如果有的話)傳回到連接配接表上。調用free函數時,它将使用者釋放的記憶體塊連接配接到空閑鍊上。到最後,空閑鍊會被切成很多的小記憶體片段,如果這時使用者申請一個大的記憶體片段,那麼空閑鍊上可能沒有可以滿足使用者要求的片段了。于是,malloc函數請求延時,并開始在空閑鍊上翻箱倒櫃地檢查各記憶體片段,對它們進行整理,将相鄰的小空閑塊合并成較大的記憶體塊。如果無法獲得符合要求的記憶體塊,malloc函數會傳回NULL指針,是以在調用malloc動态申請記憶體塊時,一定要進行傳回值的判斷。

calloc:

void *calloc(unsigned n,unsigned size);
           
  • 功能:在堆區申請連續的 num 塊記憶體,每塊記憶體的位元組數為size;并将這些位元組置為初始化為0,傳回值為所申請空間的首位址,申請數組時比較友善,但是效率可能比malloc()會慢一點,因為多了一步初始化操作
  • 參數:n--連續的塊記憶體數,size--每塊記憶體的位元組數
  • 傳回值:如果配置設定成功則傳回指向被配置設定記憶體的指針(此存儲區中的初始值不确定)即申請空間的首位址,否則傳回空指針NULL。當記憶體不再使用時,應使用free()函數将記憶體塊釋放。函數傳回的指針一定要适當對齊,使其可以用于任何資料對象。
  • 注意:void* 表示未确定類型的指針,更明确的說是指申請記憶體空間時還不知道使用者是用這段空間來存儲什麼類型的資料(比如是char還是int或者...)

realloc:

void* realloc(void* memblock, size_t size);
           
  • 功能:先判斷目前的指針是否有足夠的連續空間,如果有,擴大memblock指向的位址,并且将memblock傳回,如果空間不夠,先按照size指定的大小配置設定空間,将原有資料從頭到尾拷貝到新配置設定的記憶體區域,而後釋放原來memblock所指記憶體區域,同時傳回新配置設定的記憶體區域的首位址。即重新配置設定存儲器塊的位址。
  • 參數:membloc--目前的記憶體塊指針, size--擴大指定
  • 傳回值:如果配置設定成功則傳回指向被配置設定記憶體的指針(此存儲區中的初始值不确定)即申請空間的首位址,否則傳回空指針NULL。當記憶體不再使用時,應使用free()函數将記憶體塊釋放。函數傳回的指針一定要适當對齊,使其可以用于任何資料對象。
  • 注意:void* 表示未确定類型的指針,更明确的說是指申請記憶體空間時還不知道使用者是用這段空間來存儲什麼類型的資料(比如是char還是int或者...)

 _alloca:

void * __cdecl alloca(size_t);
           

記憶體配置設定函數,與malloc,calloc,realloc類似,但是注意一個重要的差別,_alloca是在棧(stack)上申請空間,用完馬上就釋放.

在調用 alloca() 的函數傳回的時候, 它配置設定的記憶體會自動釋放。也就是說, 用 alloca 配置設定的記憶體在某種程度上局部于函數的 ``堆棧幀"  或上下文中。alloca() 不具可移植性, 而且在沒有傳統堆棧的機器上很難實作。 當它的傳回值直接傳入另一個函數時會帶來問題。

 fgets(alloca(100), 100, stdin)
           

由于這些原因, alloca() 不合标準, 不宜使用在必須廣泛移植的程式中, 不管它可能多麼有用。 既然 C99 支援變長數組(VLA), 它可以用來更好的 完成 alloca() 以前的任務。不提倡使用

new/new[]

  • 功能:在堆區申請空間長度為目前類型(目前類型*數組)位元組連續的記憶體塊。
  • 參數:void
  • 傳回值:如果配置設定成功則傳回指向被配置設定記憶體的指針(此存儲區中的初始值不确定)即申請空間的首位址,否則傳回空指針NULL。當記憶體不再使用時,應使用delete delete[]函數将記憶體塊釋放。
  • 注意:new對象時候會自動調用構造函數。

free

void free(void *ptr)
           
  • 功能:釋放記憶體塊。
  • 參數:ptr--指針指向一個要釋放記憶體的記憶體塊,該記憶體塊之前是通過調用 malloc、calloc 或 realloc 進行配置設定記憶體的。如果傳遞的參數是一個空指針,則不會執行任何動作。
  • 傳回值:void
  • 注意:free()不能去釋放棧區的空間,棧區空間是由OS管理的,由OS進行申請和釋放。釋放空間後,指針需要置空,避免成為野指針

delete/delete[]

  • 功能:釋放記憶體塊。
  • 傳回值:void
  • 注意:因使用delete對象時候會自動調用析構函數,對象數組空間必須使用delete[]進行釋放,基本類型數組空間可以delete/delete[]進行釋放。delete不能去釋放棧區的空間,棧區空間是由OS管理的,由OS進行申請和釋放。釋放空間後,指針需要置空,避免成為野指針