2014-05-22 26 views
7

Sen K & R en C Programlama Dili bu kodu bulabilirsiniz:Malloc için K & R C örneğinde gereksiz yere sıralanmamış çizgi var mı?

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; /* STRANGE LINE???????? */ 
      } 
      freep = prevp; 
      return (void *)(p+1); 
     } 
     if (p == freep) /* wrapped around free list */ 
      if ((p = morecore(nunits)) == NULL) 
       return NULL; /* none left */ 
    } 
} 

Orada temelde bir bağlantılı liste ve listedeki her düğüm belirten bir başlık ile başlar (http://pelusa.fis.cinvestav.mx/tmatos/LaSumA/LaSumA2_archivos/Supercomputo/The_C_Programming_Language.pdf itibaren) Bir sonraki düğüm ve düğümün başlıktan sonra tahsis ettiği bellek miktarı (başlık boyutunun katları). Bu bağlantılı liste, boş hafıza olduğu yerleri izler.

Neyi anlamadığım "STRANGE LINE ?????" gereklidir. İlk ikisini anlıyorum. Düğümün sonunu kullanıcıya vermek istiyoruz, bu yüzden boyutu küçültüyoruz ve p'u yeni boyutla ilerletiyoruz ve bunu kullanıcıya veriyoruz (+1). Fakat sonra üçüncü satır, p noktanın büyüklüğünü birimlerin sayısına ayarlamak istiyor. Niye ya? İkinci satırdan sonra p boş bellekte herhangi bir anlamı olmayan bir noktaya işaret eder. Bu bir çeşit hileli optimizasyonun farkında değil miyim, yoksa gerçekten gerekli mi?

Yardımlarınız için teşekkürler!

cevap

7

Bu satırı anlamadığınızın sebebi, bunun tek başına anlaşılamamasıdır: malloc bakış açısından, faydasızdır. Bu atama, ilgili listeye bellek bloğunu serbest listesine eklemek için ayrılan boyutu bilmesi gereken ilgili free işlevinin işlevselliğini desteklemek amacıyla yapılır.

void free(void *ap) 
{ 
    Header *bp, *p; 
    bp = (Header *)ap - 1; /* point to block header */ 
    for (p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) 
     if (p >= p->s.ptr && (bp > p || bp < p->s.ptr)) 
      break; /* freed block at start or end of arena */ 
    /* Here is where the saved size comes into play */ 
    if (bp + bp->size == p->s.ptr) { /* join to upper nbr */ 
     bp->s.size += p->s.ptr->s.size; 
     bp->s.ptr = p->s.ptr->s.ptr; 
    } else 
     bp->s.ptr = p->s.ptr; 
    if (p + p->size == bp) { /* join to lower nbr */ 
     p->s.size += bp->s.size; 
     p->s.ptr = bp->s.ptr; 
    } else 
     p->s.ptr = bp; 
    freep = p; 
} 

Gördüğünüz gibi

, boyut hemen önce arayana döndürdüklerine bayt squirreled edilir. Bu, "defter tutma" için malloc ve free'un kullandığı başlık kısmıdır.

+0

Mükemmel cevap, teşekkürler. Şimdi, neden sadece "p" yerine "p + 1" döndürdüğünü de görüyorum! – bombax

+0

çünkü "p" 'de tahsis edilen parçayı tanımlayan meta verilere sahip olursunuz ... 'p'' Header' türündedir, sonra ilk "kullanıcı free" baytı 'p + 1'de –

İlgili konular