1. 程式人生 > >C語言中關於malloc(0)問題

C語言中關於malloc(0)問題

首先來解釋malloc(0)的問題,這個語法是對的,而且確實也分配了記憶體,但是記憶體空間是0,就是說返回給你的指標是不能用的,感覺奇怪吧?但是從作業系統的原理來解釋就不奇怪了,這要涉及作業系統維護記憶體的方法來說了,在記憶體管理中,記憶體被分為2部分,棧和堆,棧有自己的機器指令,是一個先進後出的資料結構,我就在這裡不再過多解釋了,malloc分配的記憶體是堆記憶體,由於堆沒有自己的機器指令,所以要有系統自己編寫演算法來管理這片記憶體,通常的做法是用連結串列,在每片被分配的記憶體前加個表頭,裡面儲存了被分配記憶體的起始地址和大小,你的malloc返回的就是表頭裡的起始指標,這個地址是由一系列的演算法得來了,通常不會為0,一旦分配成功,就返回一個有效的指標,對於分配0空間來說,演算法已經算出可用記憶體的起始地址,但是你佔用0空間,所以對那個指標操作就是錯誤的,作業系統一般不知道其終止地址,因為有佔用大小就可以推出終止地址,還有就是即使分配0空間也要釋放它,其實是釋放的連結串列結點。

還有,返回的指標是可用地址的起始地址,可用大小是固定的,在VC6下是56位元組,這個大小可能就是連結串列的大小。下面有我在其他部落格摘取的一段論述:

既然malloc另外分配記憶體來維護該記憶體塊(演算法連結串列佔用大小),也就是說分配來用於維護該記憶體塊的記憶體的大小也是有限的,那麼到底是多少呢?這和可能也依賴於實現,在VC6下,是56BYTE,下面是測試程式:

#include 
#include 
#include

int main()
{
 char *ptr ;
 ptr = malloc(0*sizeof(char)) ;
 
 if (NULL == ptr)
  printf("got a NULL pointer\n");
 else 
 {
  printf("got a Valid pointer\n");
  // 有56個a,另外有一個位元組用於儲存''\0'
  strcpy(ptr,"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); 
  //printf("the value at %X is:%c\n",ptr,*ptr);
  printf("the string at %x is :%s\n",ptr, ptr);
 // free(ptr);
 }
 return 0 ;
}

此時我們沒有把free(ptr)編譯進來,同樣會發生異常,程式輸出很多個56個a,我暫時還不明白為什麼?????如果把free(ptr);編譯進來,就會發生執行錯誤!

通過上面的討論和程式的驗證,確實證明了網友和我的想法是正確的,也就是malloc(0)還會額外分配一部分空間(在VC6下是56位元組)用於維護記憶體塊。