2017-10-13 45 views
3

http://en.cppreference.com/w/c/memory/malloc嚴格來說,C標準是否要求在malloc之後必須調用free,以及在不滿足此要求時規定了什麼?

返回的指針必須用免費被解除分配()或realloc()。

http://en.cppreference.com/w/c/memory/calloc

返回的指針必須用免費被解除分配()或realloc()。

嚴格地說,爲什麼必須返回指針被釋放?

現在我知道POSIX強制內存將在程序終止時被釋放,所以在實踐中調用malloc並立即終止不會造成任何傷害。但這不是我所問的。

這是硬要求(「必須被解除分配」)存在於C標準,或這是cppreference貢獻者的發明,督促程序員不泄漏存儲器?如果這樣的硬性要求是存在於標準,這是否意味着,按照C標準(POSIX和其他操作系統相關的東西放在一邊!),該計劃是UB如果malloc返回的指針不是free「d,或做該標準是否定義了未能達到這一要求的後果? (這將是特別有趣,因爲這可能意味着標準涉及當程序已經終止會發生什麼!)

+2

在某些應用程序中,永不終止的嵌入式應用程序,可能是您調用malloc(),但永遠不會釋放()以構建將永久生存的內部數據結構,或者直到有人拉動電源線。所以在這種情況下,完成_requirement_來釋放分配的內存塊是不可能的。 – user1048576

+2

我一直在閱讀這個語句,如下所述:「如果你想釋放內存,你必須使用'free()'或'realloc ()'」。 –

+1

我認爲重點不在於「必須」,而在於「自由」。當該塊被釋放時,必須使用「free」功能。 –

回答

0

C不要求你給free()分配後的內存。

副作用是內存泄漏。但是你不會看到任何錯誤或警告。這是您作爲程序員修復的工作。

6

當他們說上cppreference.com「返回的指針必須用免費被釋放」,但並不意味着作爲當務之急,程序員必須做的。它的意思更多的是「當分配的內存被釋放時,它必須用free或realloc來完成,因爲只有這些函數能夠正確執行。」實際規格中沒有這樣的要求。

1

儘管realloc()free()將是C語言中最自然的釋放內存的方式,但在C++中釋放內存的最自然的方式是delete。雖然鏈接的頁面描述了C中的行爲,但該語言與描述C++行爲的頁面並行:

成功時,返回指向新分配內存開始處的指針。返回的指針必須用std :: free()或std :: realloc()釋放。

我懷疑描述C++文本的預期目的是爲了清楚地表明釋放存儲,包括delete,其他手段不適合於與來自std::mallocstd::calloc接收的存儲的使用;即使C沒有任何其他預計可行的方法,在描述C時也會出現相同的文本。

+0

我不知道,也許有人會想到使用'munmap'或'sbrk'來代替'free'的負值嗎?我覺得這不太可能,儘管 – gaazkam

+0

@gaazkam:實現可能提供其他釋放內存的方式,但free和realloc()是標準提供的唯一兩個。 – supercat

+0

在malloc之後使用sbrk會導致未定義的行爲:http://pubs.opengroup.org/onlinepubs/7908799/xsh/brk。html – mnistic

0

不,絕對沒有要求釋放任何內存。這樣做是爲了你自己,允許實現再次使用它來滿足未來對malloc的調用。另外,C沒有任何關於你的機器/操作系統在C程序之外或終止之後的狀態。指定這取決於操作系統或管理它的標準,實際上對於任何多進程操作系統,由malloc和其他類似資源獲得的內存都會終止進程。

+0

我同意C標準並不要求你釋放內存,但是在你的程序終止後它沒有關於你的機器狀態的評論與解釋這一點無關。 C標準可以指定一個終止而不釋放分配的內存的程序會產生一些錯誤消息或者它在退出時的行爲是未定義的等等。也就是說,標準理論上可以強制要求釋放記憶而不強加任何終止後要求。 –

+0

@EricPostpischil:第二段更多地解決了「在程序結束時依靠操作系統釋放所有內容」「不可移植」的問題這一常見誤解。第一段已經提到缺乏對「免費」的要求。 –

0

句子返回的指針必須用free()或realloc()解除分配,C11 standard draft n1570中不存在。

嚴格地說,標準並沒有說對象必須被釋放。它甚至沒有明確表示內存塊需要被freerealloc釋放 - 這只是該標準沒有提供可用於釋放空間的任何其他函數。

但同時,也不能保證他們正在釋放的程序退出或者 - 相反,所有的語言開闢了可能性,即通過main進入程序仍然可以通過沒有要求free內存泄漏,並仍在運行一個符合實施。標準說,在6.2.4p2

2的對象的生存期是程序執行其間存儲是保證被保留用於它部分。一個對象存在,具有一個常數地址,並且在其整個生命週期中保留其最後存儲的值.34)如果一個對象被引用到其生命週期之外,則該行爲是未定義的。指針的值在其指向的對象(或剛剛過去)達到其生命週期結束時變得不確定。

和在7.22.3p1

一個已分配對象的生存期從分配,直到解除分配延伸。

就是這樣。 C標準不關心在之後發生的任何事情程序執行已經終止。這是行爲未定義的行爲,所以任何可能的行爲都是符合標準的。

相關問題