2012-03-15 53 views
11

下面的代碼在Windows中執行時返回一個地址,但我期待它返回NULL。爲什麼malloc(0)在Windows中返回一個非空地址?

int main() 
{ 
    char *ptr = NULL; 
    ptr = malloc(0); 
    printf("malloc returned = %u\n", ptr); 

} 

什麼能促使的malloc這樣的實現?它背後有什麼理由嗎?

因爲這是一個0字節的內存,我沒有試驗寫入任何數據。但是,這個記憶可以用於任何事情嗎?

回答

9

這只是最小尺寸你的要求。而且,由於不存在零長度塊在Win32堆,您可以:

void *p = malloc(0); 
// ... do some stuff in between... 
realloc(p, n); 

這應該主要是導致重用堆塊(如果你是幸運的,新的尺寸小)。少量機會主義優化(或緩慢下降,取決於背景和血液咖啡水平)。

這是一個簡化的例子。實際情況可能是一個在創建緩衝區時分配一個緩衝區的類,並且還可以增加它。如果輸入令人討厭的控制,你可以讓它做零大小的緩衝區分配。

+0

+1,因爲我實際上已經看到1個人使用這個來獲得他的「優勢」,當他不想特殊情況下可以增加malloc'd/realloc內存非常大的循環。 – JimR 2012-03-15 15:47:18

+1

雖然你可以傳遞一個空指針到'realloc',所以這個竅門絕不是必須的。你也可以'void * p = 0;'。 – 2012-03-15 16:04:22

+0

@Steve這不是一個詭計。這是編程和鬆散平臺規範的人爲因素。例如,在沒有測試的情況下,HeapRealloc(heap,HEAP_REALLOC_IN_PLACE_ONLY,0,4)如何表現並不清楚。 – ActiveTrayPrntrTagDataStrDrvr 2012-03-15 16:08:35

7

那是comp.lang.c常見問題中回答:http://c-faq.com/ansi/malloc0.html

的ANSI/ISO標準說,它可能會做任何;行爲是實現定義的(參見問題11.33)。可移植代碼必須注意不要調用malloc(0),或者準備好返回空值的可能性。

+0

但是,什麼會使一個實現選擇返回一些有效的值?在所有情況下返回NULL是否有意義? – Jay 2012-03-15 15:42:36

+3

不一定。我對第二次猜測的編譯器編寫者感到不寒而慄,但是實現者可能希望malloc只有在內存不能真正分配的情況下才返回'null'。 – CAbbott 2012-03-15 15:46:11

+1

@Jay:由於實現可以自由執行,它可能會決定做更少的代碼。決定不麻煩編寫額外的代碼行來測試輸入爲0並返回空指針是合理的。然後,如果實現已經有了一個測試,即所需的大小不是非常大(並且如果是的話會返回一個空指針),那麼檢查荒謬的巨大或零就可能很容易。 – 2012-03-15 16:06:40

8

要回答問題的第二部分no,內存不能用於任何事情,因爲「可訪問的部分」是從返回的地址開始的0個字節。

IIRC它是保證,但如果執行確實返回非空,那麼它將是一個不同的地址從任何其他當前分配的內存塊。所以理論上你可以使用地址作爲臨時唯一ID(指針類型),儘管顯然有很多其他的方法來獲得唯一的ID。即使你打算使用它,malloc(1)也可以和malloc(0)一樣工作,並且更便於攜帶。

0

這不是沒用的。預計從malloc返回的塊是唯一的。因此,malloc返回的每個塊都攜帶塊內的數據以及它的唯一標識符(即其地址)。如果後者的屬性很重要,並且它不包含數據的事實不是問題,那麼它很有用。

但是,正如前面提到的那樣,它是編寫非可移植代碼的好方法。然而,這與非法代碼並不相同,並且對於支持它的實現來說它是完全有效的(就像Windows明顯那樣)。

相關問題