天天看點

malloc()參數為0的情況

下面的代碼片段輸出是什麼?為什麼?

 解析:......故意把0值傳給了函數malloc,得到了一個合法的指針,這就是上面的代碼,該代碼的輸出是"Got a valid pointer"。

  這個“解析”根本就沒有解析嘛。好在查資料很友善,《C語言參考手冊》上說“如果請求的長度為0,則标準C語言函數傳回一個null指針或不能用于通路對象的非null指針。”或者你也可以直接在linux裡man malloc來查閱手冊:

void *malloc(size_t size); ... malloc() allocates size bytes and returns a pointer to the allocated memory. The memory is not cleared. If size is 0, then malloc() returns either NULL, or a unique pointer value that can later be successfully passed to free().

  可見,原題的if是為了鑒别malloc()傳回值是NULL,還是一個唯一的待釋放指針;而不是“解析”中的必然是非NULL的“合法指針”,是以輸出也不是确定的,盡管我用gcc和clang多次編譯運作,輸出都是"Got a valid pointer"。

  順便再說說後面的代碼,同樣出自《程式員面試寶典》:

将程式改成:

或者

如果求ptr的strlen的值和sizeof的值,該代碼的輸出是"Got a null pointer"。

  第一段程式的分析和上面一樣,如果不幸傳回了一個唯一的待釋放非NULL指針,行為不可預測;隻不過這個if判斷寫的有些繁瑣:注意到“==”優先級高于"=",而指派語句的值是其左值。

  此時malloc(0)傳回了一個可用于free()釋放的唯一指針(非NULL),而且将它傳給strlen(),傳回值為0,這樣看來,它用‘\0‘進行填充的(即内容是NULL而非指針指向NULL)。但這一點并沒有在man中提到,個人猜測是和實作有關的。

  除此以外,順便考察了strlen((char*)NULL)的行為:會導緻段錯誤。

  第二段程式呢,sizeof()裡寫了一大堆,其實隻是計算了sizeof(char *),在32位機上結果當然是4,而sizeof()裡面的malloc()根本沒有執行。和前面兩段代碼不同,關鍵點不在malloc而是sizeof。

  對于提到的問題“實際項目中什麼情況下會給malloc傳0?既然是開辟記憶體,傳0不是沒有意義嗎?”的個人了解:

1.一般确實不會直接寫malloc(0),但是可能在程式某個地方寫int n;int *p = malloc(n);在别的地方又令n=0,造成了參數為0的情況。若是無心而為,可能導緻某種bug。如果了解malloc(0)的行為,找bug相對而言會簡單點。

2.面試題各種稀奇古怪的問題都有可能出現,有的面試官認為考這些邊界條件、特殊參數什麼的能考察一個程式員的功底