2012-05-26 1 views
4

이 코드는 K & R 서적 - 8 장 섹션 7 : 예 - 저장 장치 할당 자입니다. 최소한이 코드는 의미가 없습니다. "머리글"은 구조체와 긴 형식 인 "가장 제한적인 정렬 유형"의 합집합입니다. Malloc은 헤더 크기의 배수 크기의 충분한 여유 공간을 찾습니다.K & R malloc 코드가 맞지 않습니까?

static Header base;   /* empty list to get started */ 
static Header *freep = NULL; /* start of free list */ 

/* malloc: general-purpose storage allocator */ 
void *malloc(unsigned nbytes) 
{ 
    Header *p, *prevp; 
    Header *morecore(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 */ 

    } 
} 

이 코드의 이상한 부분은 헤더의 크기면에서 단위 충분히 큰 공간을 찾기 위해 비교 if (p->s.size >= nunits)에서 사용되는 문 nunits = (nbytes+sizeof(Header)-1)/sizeof(Header) + 1;입니다. 전자가 nunits = (nbytes+sizeof(Header))/sizeof(Header)일까요? 원래의 코드는해야 할 것보다 적은 값으로 평가됩니다. + -1은 무엇입니까? 왜 원하는 것보다 적은 공간을 할당해야 하는가?

+1

운영자의 우선 순위를 염두에두고 다시 분석하십시오. –

+6

@duffymo : 그게 아니라 코드가 어떻게 작동하는지 말해 줄 수 있습니까? 그건 그렇고, 그 책 읽었 니? 많은 오타가 있음을 알았습니까? 그러나 아무도 그런 말을하지 않았습니다. – 1der

+0

이것이 malloc에 ​​대한 첫 번째 호출이라고 가정하고 1 바이트 즉,'malloc (1)'을 요청하고 제안 된 수정과 코드에서'nunits'가 반환하는 것을 본다. – dirkgently

답변

10

-1+1은 블록 크기의 배수가 아닌 값을 고려해야합니다.

예를 들어

, 당신은 당신이 잘못 15. 당신이 필요 = n은 1 개 블록을 얻을 것입니다 필요한 블록 수를 얻을 수있는 공식 n/10를 사용하려고하면 블록 크기는 10입니다 가정 2.

수식을 n/10 + 1으로 변경하면 잘못 될 수도 있습니다. n = 20 인 경우 2 블록 만 필요하지만 해당 수식은 3을 반환합니다.

올바른 수식은 (n - 1)/10 + 1입니다. 그것은 정수 나누기로 반올림하는 방법입니다. 이것과 유일한 차이점은 물어 본 수식은 여분의 sizeof(Header)입니다. 이것은 헤더 자체에 필요한 여분의 공간입니다.

+0

정말 고마워. 실제로 혼란은 분할 기호 '/'를 전체 단위로 사용한 다음 표현식을 고려한 사실에서 비롯된 것입니다. – 1der

+0

'(n + 9)/10'을 사용하는 것이 더 간단하지 않습니까? –

+0

@JoshuaGreen : 예, 그게 제가 보통 사용하는 것입니다. –

3

(nbytes+sizeof(Header)-1)/sizeof(Header) + 1은 정확한 반올림을 사용하여 무언가의 단위 수를 얻는 코드의 꽤 표준적인 관용구입니다. 일부 값으로 시도하면 올바르게 작동하는 것을 볼 수 있습니다.

실제 관용구는 (nbytes - 1)/unitSizeInBytes + 1으로 표현하는 것이 좋습니다.

허용되는 답변의 마지막 단락을 기반으로, sizeof(Header)의 사용은 부서의 양쪽에서 다릅니다. 배당금의 용도는 Header 및 Nbytes에 대해 바이트를 할당해야하기 때문입니다. 제수에서 사용하는 것은 할당되는 블록의 크기이기 때문입니다. 이 경우 동일한 값인 sizeof(Header)이 발생합니다.

+0

예, K-ballo가 말했듯이 운영자 우선 순위를 고려하십시오. –

+0

이 표준 숙어에 익숙해 지려면 다른 사람들의 코드를 많이 읽어야 함을 의미합니까? – 1der

+0

예, 그렇습니다. 이와 같은 질문을하는 것도 좋은 생각이지만,하기 전에 신중하게 공부하십시오. 좋은 오픈 소스 코드를 읽으십시오. 그런 다음 작업하십시오. 세상을 더 좋게 만드십시오. :) –