2010-09-10 58 views
11

realloc用於動態重新分配內存。如果沒有連續的內存空間,realloc會做什麼?

假設我已經使用malloc功能分配的7個字節,現在我想將其擴展到30個字節。

會在後臺發生什麼,如果沒有連續的(汽車無以單行)的30個字節的內存空間?

是否有任何錯誤或將內存中的部分被分配?

回答

11

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; 
    } 
} 
+0

這是'realloc'適用於所有實現嗎? – 2016-02-29 15:18:24

+0

@CoolGuy:有些實現可能無法(能夠)執行擴展當前塊的第一步,但否則這是所有實現的'realloc'的可觀察行爲。 – 2016-02-29 16:40:21

1

man page

realloc()的指針返回到該 新分配的存儲器,這是 任何種類 變量的適當對準,並且可以不同於 PTR,或NULL,如果請求失敗。

換句話說,要檢測失敗,只要檢查結果是否爲NULL。

編輯:正如評論指出的那樣,如果調用失敗,原來的內存不釋放。

+2

從手冊頁值得注意的是:如果realloc()失敗,原始塊保持不變;它沒有被釋放或移動。 – 2010-09-10 11:43:49

6

realloc纔會成功,如果它可以返回一個連續的(在你的話「序」)的內存塊。如果沒有這樣的塊存在,它將返回NULL

+4

@Mark - 原始內存保持不變。這種情況下的一個常見錯誤是'x = realloc(x)' - 您必須執行'newX = realloc(x)'以避免錯誤地泄漏原始x。 – 2010-09-10 11:43:53

+0

@Steve Townsend - 只有在儀式失敗時纔會出現?成功時釋放原始指針。還有誰在這個頁面上標記? O_o – 2010-09-10 11:47:00

+0

我想這是一個錯誤。第一條評論是從用戶銳利的角度顯示出來的,現在它發生了變化,但都是針對Mark的。那是一個錯誤? :-P – 2010-09-10 11:50:56

1

一般而言,這取決於執行。在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。

0

FreeBSD和Mac OS X上有reallocf()函數,當請求的內存不能分配時會釋放傳遞的指針(請參閱man realloc)。

+0

而不是使用它,如果你真的想要這樣的行爲,那麼只需編寫自己的函數就可以做到這一點。但我無法想象它是非常有用的 - 它扔掉可能有價值的數據。 – 2010-09-10 16:25:54

相關問題