1. 程式人生 > >alloc()、malloc()、calloc()、realloc()區別及用法

alloc()、malloc()、calloc()、realloc()區別及用法

CA 這一 首地址 動態分配內存 調用函數 空指針 size 指針類型 空間

C語言跟內存申請相關的函數主要有 alloca,calloc,malloc,free,realloc,sbrk等.

函數malloc()和calloc()都可以用來動態分配內存空間,但兩者稍有區別。
  malloc()函數有一個參數,即要分配的內存空間的大小:

  void *malloc(size_t size);

  calloc()函數有兩個參數,分別為元素的數目和每個元素的大小,這兩個參數的乘積就是要分配的內存空間的大小。

  void *calloc(size_t numElements, size_t sizeOfElement);

  如果調用成功,函數malloc()和函數calloc()都將返回所分配的內存空間的首地址。

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

  malloc()函數的工作機制

  malloc函數的實質體現在,它有一個將可用的內存塊連接為一個長長的列表的所謂空閑鏈表。調用malloc函數時,它沿連接表尋找一個大到足以滿足用戶請求所需要的內存塊。然後,將該內存塊一分為二(一塊的大小與用戶請求的大小相等,另一塊的大小就是剩下的字節)。接下來,將分配給用戶的那塊內存傳給用戶,並將剩下的那塊(如果有的話)返回到連接表上。調用free函數時,它將用戶釋放的內存塊連接到空閑鏈上。到最後,空閑鏈會被切成很多的小內存片段,如果這時用戶申請一個大的內存片段,那麽空閑鏈上可能沒有可以滿足用戶要求的片段了。於是,malloc函數請求延時,並開始在空閑鏈上翻箱倒櫃地檢查各內存片段,對它們進行整理,將相鄰的小空閑塊合並成較大的內存塊。


  函數calloc()會將所分配的內存空間中的每一位都初始化為零,也就是說,如果你是為字符類型或整數類型的元素分配內存,那麼這些元素將保證會被初始 化為0;如果你是為指針類型的元素分配內存,那麼這些元素通常會被初始化為空指針;如果你為實型數據分配內存,則這些元素會被初始化為浮點型的零。

  alloca是向棧申請內存,因此無需釋放. alloc與afree以棧的方式(即後進先出的列表)進行存儲空間的管理。

  realloc(void *__ptr, size_t __size):更改已經配置的內存空間,即更改由malloc()函數分配的內存空間的大小。

  如果將分配的內存減少,realloc僅僅是改變索引的信息。

  如果是將分配的內存擴大,則有以下情況:
  1)如果當前內存段後面有需要的內存空間,則直接擴展這段內存空間,realloc()將返回原指針。
  2)如果當前內存段後面的空閑字節不夠,那麽就使用堆中的第一個能夠滿足這一要求的內存塊,將目前的數據復制到新的位置,並將原來的數據塊釋放掉,返回新的內存塊位置。
  3)如果申請失敗,將返回NULL,此時,原來的指針仍然有效。

  註意:如果調用成功,不管當前內存段後面的空閑空間是否滿足要求,都會釋放掉原來的指針,重新返回一個指針,雖然返回的指針有可能和原來的指針一樣,即不能再次釋放掉原來的指針。

alloc()、malloc()、calloc()、realloc()區別及用法