1
爲函數malloc()的代碼的低於困惑K&R執行以K & R段8.7的malloc
void *malloc(unsigned nbytes) {
Header *p, *prevp;
Header *moreroce(unsigned);
unsigned nunits;
nunits = (nbytes+sizeof(Header)-1)/sizeof(header) + 1;
if ((prevp = freep) == NULL) { /* no free list yet */
base.s.ptr = freeptr = prevptr = &base;
base.s.size = 0;
}
for (p = prevp->s.ptr; ; prevp = p, p = p->s.ptr) {
if (p->s.size >= nunits) { /* big enough */
if (p->s.size == nunits) { /* exactly */
prevp->s.ptr = p->s.ptr;
} else { /* allocate tail end */
p->s.size -= nunits;
p += p->s.size;
p->s.size = nunits;
}
freep = prevp;
return (void *)(p+1);
}
if (p == freep) /* wrapped around free list */
if ((p = morecore(nunits)) == NULL)
return NULL; /* none left */
}
}
我主要是由「分配尾端」部分相混淆。根據代碼,我們首先從p-> s.size中減去2,將p前進3,在該地址記錄分配的大小,並返回(void *)(p + 1)。
設p'表示自增後的p,*表示自由空間。上述操作後,內存應該是這樣的:
P * * P」 *
實際上我們分配了2個單位的內存,但對於p剩餘的可用空間應該是2,而不是3,因爲一個單元被分配的尾端的頭部信息佔用。
所以我覺得行
p->s.size -= nunits;
應
p->s.size -= nunits + 1;
代替我錯過了什麼?
謝謝您的澄清!我混淆了這兩個變量。但如果是這樣,不應該p自增加p-> s.size + 1而是爲了得到正確的頭部位置? – Loopz
這由返回'p + 1'的'return'語句處理。基本上,代碼基於塊的概念,其中包括標題,數據和填充。它在開始時調整請求大小,並在末尾調整指針。兩者之間的所有內容都使用塊指針。 – user3386109
仍然假設p-> s.size = 5。我們有從0到5索引的內存地址。p最初是0,它有1到5的空閒內存。如果nbytes = 2,我認爲p應該前進到4並且返回5.但似乎p提前到3,而返回4。 – Loopz