2013-02-22 2 views
3

Im은 C++에 새로운 기능입니다.하지만이 버디 시스템 메모리 할당 코드는 발견되었지만 주요 기능이 없으므로 모든 멤버 함수가 정확합니다. 사용자가 주요 기능을 도와 주었으면합니다. 할당하고 싶습니다. 다음 약간 메모리 할당 이전과 이후의 메모리의 상태를 도시하고 친구 병합되었는지 확인하기 위해 상기 메모리의 할당을 해제하고, 자유 블록리스트를 표시버디 메모리 할당 - 주 기능

--BuddyPool.h--

#ifndef BUDDYPOOL_INC 
#define BUDDYPOOL_INC 

class BuddyPool{ 
public: 
    enum Status { free, reserved }; 
    struct Header 
    { 
     Status status: 1; 
     //unsigned int k : bitsizeof(unsigned int) - 1U; 
     unsigned int k : 31; 
    }; 
    struct Block : public Header 
    { 
     //enum { size = 16 }; 

     enum { size = 64 }; 
     struct Links 
     { 
      Block *next; 
      Block *prev; 
     }; 
     union 
     { 
      Links link; 
      char userPart [size - sizeof(Header)]; 
     }; 
    }; 

private: 
    unsigned int m; 
    unsigned int numberOfBlocks; 
    Block *pool; 
    Block *sentinel; 

    static void Unlink(Block &); 
    static void InsertAfter(Block &, Block &); 
    Block &Buddy(Block &) const; 

public: 
    BuddyPool(size_t); 
    ~BuddyPool(); 

    void *Acquire(size_t); 
    void Release(void *); 
}; 

#endif /* ----- #ifndef BUDDYPOOL_INC ----- */ 

--BuddyPool.cpp--

#include <WinDef.h> 
#include "BuddyPool.h" 

unsigned int Log2Ceil(unsigned int val){ 
    unsigned int L; 
    for (L = 0; (1ul<<L) < val; L++); 
    return L; 
} 

BuddyPool::BuddyPool(size_t bytes) 
    : m(Log2Ceil(bytes)) 
    , numberOfBlocks((1 << m)/sizeof(Block)) 
    , pool (new Block[numberOfBlocks + m +1]) 
    , sentinel(pool + numberOfBlocks) 
{ 
    for (unsigned int i = 0; i <= m; ++i) { 
     sentinel[i].link.next = &sentinel[i]; 
     sentinel[i].link.prev = &sentinel[i]; 
    } 

    Block &head = pool[0]; 
    head.status = free; 
    head.k = m; 
    InsertAfter(sentinel[m], head); 
} 

BuddyPool::~BuddyPool(){ 
    delete [] pool; 
} 

void *BuddyPool::Acquire(size_t bytes){ 
    unsigned int kPrime = Log2Ceil(bytes + sizeof(Header)); 

    unsigned int i = kPrime; 
    while (i <= m && sentinel[i].link.next == &sentinel[i]) { 
     ++i; 
    } 
    if (i > m) { 
     return NULL; // throw bad_alloc("out of memory"); 
    } 

    Block &block = *sentinel[i].link.next; 
    Unlink(block); 
    while (block.k > kPrime) { 
     block.k -= 1; 
     Block &buddy = Buddy(block); 
     buddy.status = free; 
     buddy.k = block.k; 
     InsertAfter(sentinel[buddy.k], buddy); 
    } 
    block.status = reserved; 
    return block.userPart; 
} 

void BuddyPool::Release(void *arg){ 
    Block &block = *reinterpret_cast<Block *>(
               reinterpret_cast<Header *>(arg) - 1U); 

    if (&block < pool || &block >= pool + numberOfBlocks) { 
     return; // throw invalid_argument("invalid pointer"); 
    } 

    block.status = free; 
    Block *ptr; 
    for (ptr = &block; ptr->k < m; ptr->k += 1) { 
     Block &buddy = Buddy(*ptr); 
     if (buddy.status == reserved || buddy.k != ptr->k) { 
      break; 
     } 
     Unlink(buddy); 
     if (&buddy < ptr) { 
      ptr = &buddy; 
     } 
    } 

    InsertAfter(sentinel[ptr->k], *ptr); 
} 

BuddyPool::Block &BuddyPool::Buddy(Block &block) const{ 
    unsigned int addr = reinterpret_cast<unsigned int>(&block) + (1 << block.k); 
    return *(reinterpret_cast<Block *>(addr)); 
} 

void BuddyPool::Unlink(Block &block){ 
    if (block.link.next) { 
     block.link.next->link.prev = block.link.prev; 
    } 
    if (block.link.prev) { 
     block.link.prev->link.next = block.link.next; 
    } 
    block.link.next = block.link.prev = &block; 
} 

void BuddyPool::InsertAfter(Block &src, Block &block){ 
    block.link.next = src.link.next; 
    block.link.prev = &src; 

    if (src.link.next) { 
     src.link.next->link.prev = &block; 
    } 
    src.link.next = &block; 
} 

답변

3

당신은 public 함수를 호출함으로써 시작할 수 있습니다.

내부 활동을 시각화하는 것은 상당히 어렵습니다. 그것에 대한 짧은 대답은 없습니다. 파이썬과 같은 일부 언어의 경우 비주얼 라이저, 심지어 온라인 비주얼 라이저가 있지만 C++의 경우 SO 독자에게 사용자를 위해 응용 프로그램을 개발하도록 요청하는 것과 같습니다 ... l

고급 사용 : 표준 할당 자 클래스 (std::allocator 참조)를 사용하여 할당 및 할당 취소를 수행 할 수 있습니다. a std::vector.

및/또는 당신은 operator newoperator delete 일부 클래스

에 대한 (각각 단일 개체 할당 및 dellocation 기능)를 정의 할 수 있습니다