realloc
用於動態重新分配內存。如果沒有連續的內存空間,realloc會做什麼?
假設我已經使用malloc
功能分配的7個字節,現在我想將其擴展到30個字節。
會在後臺發生什麼,如果沒有連續的(汽車無以單行)的30個字節的內存空間?
是否有任何錯誤或將內存中的部分被分配?
realloc
用於動態重新分配內存。如果沒有連續的內存空間,realloc會做什麼?
假設我已經使用malloc
功能分配的7個字節,現在我想將其擴展到30個字節。
會在後臺發生什麼,如果沒有連續的(汽車無以單行)的30個字節的內存空間?
是否有任何錯誤或將內存中的部分被分配?
realloc
在幕後工作,大致是這樣的:
NULL
。所以,你可以通過測試NULL
測試失敗,但要注意,不要覆蓋舊的指針太早:
int* p = malloc(x);
/* ... */
p = realloc(p, y); /* WRONG: Old pointer lost if realloc fails: memory leak! */
/* Correct way: */
{
int* temp = realloc(p, y);
if (NULL == temp)
{
/* Handle error; p is still valid */
}
else
{
/* p now possibly points to deallocated memory. Overwrite it with the pointer
to the new block, to start using that */
p = temp;
}
}
從man page:
realloc()的指針返回到該 新分配的存儲器,這是 任何種類 變量的適當對準,並且可以不同於 PTR,或NULL,如果請求失敗。
換句話說,要檢測失敗,只要檢查結果是否爲NULL。
編輯:正如評論指出的那樣,如果調用失敗,原來的內存不釋放。
從手冊頁值得注意的是:如果realloc()失敗,原始塊保持不變;它沒有被釋放或移動。 – 2010-09-10 11:43:49
realloc
纔會成功,如果它可以返回一個連續的(在你的話「序」)的內存塊。如果沒有這樣的塊存在,它將返回NULL
。
@Mark - 原始內存保持不變。這種情況下的一個常見錯誤是'x = realloc(x)' - 您必須執行'newX = realloc(x)'以避免錯誤地泄漏原始x。 – 2010-09-10 11:43:53
@Steve Townsend - 只有在儀式失敗時纔會出現?成功時釋放原始指針。還有誰在這個頁面上標記? O_o – 2010-09-10 11:47:00
我想這是一個錯誤。第一條評論是從用戶銳利的角度顯示出來的,現在它發生了變化,但都是針對Mark的。那是一個錯誤? :-P – 2010-09-10 11:50:56
一般而言,這取決於執行。在x86(-64)Linux上,我相信標準doug lea malloc算法總是會分配最少的標準x86頁面(4096字節),所以對於上面描述的場景,它只會重置邊界以容納額外的字節。說到將7字節的緩衝區重新分配給PAGE_SIZE + 1,我認爲它會嘗試分配下一個連續頁面(如果可用)。
值得閱讀以下內容,如果你在Linux上開發:
默認情況下,Linux遵循一個樂觀的內存分配策略。這意味着當malloc()返回非NULL時,不能保證內存真的可用。這真是一個不錯的bug。如果事實證明系統內存不足,一個或多個進程將被臭名昭着的OOM殺手所殺。
# echo 2 > /proc/sys/vm/overcommit_memory
:在案件根據情況哪裏會 不太理想一下子失去了一些隨機挑選的過程,而且內核版本是足夠新採用的Linux,可以使用如下命令關閉此造成過度行爲另請參閱內核文檔目錄,文件vm/overcommit-accounting和sysctl/vm.txt。
FreeBSD和Mac OS X上有reallocf()函數,當請求的內存不能分配時會釋放傳遞的指針(請參閱man realloc)。
而不是使用它,如果你真的想要這樣的行爲,那麼只需編寫自己的函數就可以做到這一點。但我無法想象它是非常有用的 - 它扔掉可能有價值的數據。 – 2010-09-10 16:25:54
這是'realloc'適用於所有實現嗎? – 2016-02-29 15:18:24
@CoolGuy:有些實現可能無法(能夠)執行擴展當前塊的第一步,但否則這是所有實現的'realloc'的可觀察行爲。 – 2016-02-29 16:40:21