程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C >> C語言基礎知識 >> c語言中malloc、realloc與calloc 的區別以及聯系

c語言中malloc、realloc與calloc 的區別以及聯系

編輯:C語言基礎知識

ANSI C說明了三個用於存儲空間動態分配的函數
(1) malloc分配指定字節數的存儲區。此存儲區中的初始值不確定

(2) calloc為指定長度的對象,分配能容納其指定個數的存儲空間。該空間中的每一位(bit)都初始化為0

(3) realloc  更改以前分配區的長度(增加或減少)。當增加長度時,可能需將以前分配區的內容移到另一個足夠大的區域,而新增區域內的初始值則不確定

.分配函數時再分配 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函數,也有很多系統支持它。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved