代碼片段:
char *ptr = malloc(0 * sizeof(char));
if (NULL == ptr)
printf("got a NULL pointer");
else
printf("got a Valid pointer");
C99 標準規定:malloc(0) 的返回值由實現定義,但返回的指針不可解引用訪問。在 VC6 下實測輸出 "got a Valid pointer",且看似可讀寫,但 free(ptr) 卻導致運行時錯誤。這背後隱藏著怎樣的內存管理機制?
*ptr = 'a'; printf("%c", *ptr); 竟能正常輸出,編譯器無警告。free(ptr) 觸發運行時錯誤。malloc(0) 實際分配 56 字節,寫入超長字串導致異常輸出(大量重複字符),甚至未 free 也崩潰。堆分配器(如 dlmalloc、ptmalloc、VC6 CRT)在用戶請求塊前/後會維護元數據:塊大小、標誌位、空閒鏈表指針等。
malloc(0) 時,分配器仍需創建一個合法的堆塊結構以便後續管理,因此:
free 或後續分配崩潰。| 環境 | malloc(0) 返回 | 備註 |
|---|---|---|
| C99/C11 標準 | 實現定義(NULL 或唯一指針) | 指針不可解引用 |
| glibc (Linux) | 非 NULL 唯一指針 | 可 free,不可訪問 |
| MSVC (現代) | 非 NULL | 內部最小塊 32/48 字節 |
| VC6 | 非 NULL | 實測 56 字節,寫入即 UB |