簡體   English   中英

為什么malloc(0)的返回值是實現定義的?

[英]Why is the return value of malloc(0) implementation-defined?

ISO / IEC 9899:TC2(即C99標准),§7.20.3規定:

如果請求的空間大小為零,則行為是實現定義的:返回空指針,或者行為就像大小是非零值一樣,但返回的指針不應用於訪問對象。

換句話說,malloc(0)可以返回NULL或有效指針,我可能不會取消引用。

這種行為背后的理由是什么?
並且定義malloc(0)導致UB不是更容易嗎?

C99基本原理 (PDF鏈接)討論了內存管理功能(來自C99 7.20.3)並解釋:

在這些函數的定義中處理空指針和零長度分配請求部分是由支持這種范例的願望指導的:

 OBJ * p; // pointer to a variable list of OBJs /* initial allocation */ p = (OBJ *) calloc(0, sizeof(OBJ)); /* ... */ /* reallocations until size settles */ while(1) { p = (OBJ *) realloc((void *)p, c * sizeof(OBJ)); /* change value of c or break out of loop */ } 

據報道,這種編碼方式未得到委員會的認可,因此得到廣泛使用。

某些實現已為零字節的分配請求返回了非空值。
雖然這種策略具有區分“無”和“零”(未分配指針與指向零長度空間的指針)的理論優勢,但它具有更迫切的理論缺點,即需要零長度對象的概念。

由於無法聲明此類對象庫,因此它們可能存在的唯一方法是通過此類分配請求。

C89委員會決定不接受零長度物體的想法。 因此,分配函數可以返回零指針分配請求的空指針。 請注意,這種處理方法並不排除上述范例。

C89中的安靜更改 :依賴於返回非空指針的大小為零的分配請求的程序將表現不同。

因為分配0個字節實際上可能有意義。 例如,當您分配具有未知數量的項目的數組時。 UB會允許程序崩潰,而使用當前行為,您可以安全地分配numberOfItems * itemSize字節。

邏輯如下:如果你要求0字節,你會得到一個指針。 當然,您不能取消引用它,因為這將訪問第0個字節(您尚未分配)。 但是你可以安全地釋放內存。 因此,您不需要將0設為特殊情況。

這就是為什么不將malloc(0)定義為UB的原因。 關於不嚴格定義結果的決定( NULL與空白空間的唯一指針)請參閱James的回答。 (簡而言之:兩種方法都有其優點和缺點。返回唯一的非空指針的想法更具吸引力,但需要更多的概念性工作,並給實現者帶來更多負擔。)

使malloc(0)導致UB會更糟糕。 就目前而言,只要你對free通話一致,你就不必關心當大小為零時會發生什么。

問題是一些現有的實現為malloc(0)分配一個指針,一些返回空指針,並且幾乎所有實現都堅持堅持他們的行為,因為編寫實現的人寫了很多壞的,不可移植的軟件利用他們選擇的行為(GNU是這個領域最嚴重的罪犯)。 因此,標准陷入困境,允許這兩種行為讓他們都滿意。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM