2010-07-31 8 views
6

사용자 정의 메모리 관리자를 구현하려고하는데,이 함수를 구현하는 더 좋은 방법이 있다면 궁금해 할 것입니다. void 포인터 산술에 대한 질문을받을 때 여러 사람들이 내가 void * C++에서 뭔가 잘못되었습니다.사용자 정의 메모리 관리자

// allocates a page of memory. 
void ObjectAllocator::allocatePage() 
{  
    //if(OAStats_.PagesInUse_ >= Config_.MaxPages_) 
     //throw exception 

    void* buffer = ::operator new(OAStats_.PageSize_); // allocate memory, no constructor call. 

    // =============== Setup the PageList_ =============== 
    GenericObject* pNewNode = ::new(buffer) GenericObject(); // Construct GenericObject for the pagelist. 
    pNewNode->Next = PageList_->Next;       // pNewNode points to wherever PageList_ pointed to. 
    PageList_->Next = pNewNode;         // PageList_ points to pNewNode 
    pNewNode = NULL;           // dont need this handle anymore 
    buffer = static_cast<char*>(buffer) + sizeof(GenericObject); // move pointer to point after the generic object. 

    // =============== Setup the FreeList_ =============== 
    for(int i=0;i<Config_.ObjectsPerPage_;++i) 
    { 
     static GenericObject* pPreviousNode = NULL;   // static variable to hold the previous node 
     pNewNode = ::new(buffer) GenericObject();   // Construct GenericObject for the freelist. 
     pNewNode->Next = pPreviousNode; 
     pPreviousNode = pNewNode; 
     buffer = static_cast<char*>(buffer) + OAStats_.ObjectSize_; // move pointer by ObjectSize. 
     ++OAStats_.FreeObjects_; 
    } 
    FreeList_->Next = pNewNode; 

    ++OAStats_.PagesInUse_; 
    ++OAStats_.Allocations_; 
} 
+2

"여러 사람들이 C++에서 void *를 사용하면 뭔가 잘못되었다고 생각했습니다." <- 나는 그것에 동의하지 않을 것이다. 빈 포인터에는 용도가 있습니다. 나는 그것이 당신이 'anti-C'C++ 커뮤니티에 속하는지 아닌지에 달려 있다고 생각합니다. 예, C++은 C보다 더 높은 수준의 언어이지만 사람들은 종종 저수준의 것을 처리하기 때문에 더 많은 'C와 유사한'기능을 사용하는 데는 아무런 문제가 없습니다. – Stephen

+2

@Stephen : 개념이 비판적 일 때 그들은 "악의가 아니며 용도가있다"고 말할 정도로 무서운 반응을 보이는 프로그래머가 많은 이유는 무엇입니까? 나는 당신이 싱글 톤 (singletons)과 힙합 (gotos)에 관해서 똑같이 말할 것이라고 가정합니다. 그러나이 경우 void *의 용도는 무엇입니까? 왜 그는 여기에 무효 *를 사용해야합니까? – jalf

+1

@ Jalf 부정적인 주석은 사람들의 마음을 긍정적 인 코멘트보다 훨씬 더 많이 붙잡기 때문입니다. 즉, 프로그래밍에 익숙하지 않거나 이전에 X에 대해 들어 보지 못한 사람이 X를 슬레이트하고 사용해서는 안된다고 말하는 주석을 읽으면 그 지식을 취하고 그것을 사실로 생각할 수 있습니다. Moreso, 나는 단지 의견을 말하고 있었다. "void 포인터 사용 안 함"보기를 백업 한 경우 유사하게 대답하겠습니까? 아니, 그것을 사용할 아무 이유도 없었지만, OP는 단순히 사람들이 C++을 코딩 할 때 일반적으로 사용하지 말라고 말했다고 말했습니다. – Stephen

답변

7

문자열 (8 비트 ANSI)을 저장하기위한 메모리 블록이 필요한 경우 해당 버퍼에 대한 포인터를 char로 선언하고이를 조작하는 것이 좋습니다.

'blob'인 메모리 블록이 필요합니다. 고유 한 유형이 없으므로 void *를 올바르게 선택하여 해당 blob을 나타낼 수 있습니다.

이제 포인터를 개체의 크기만큼 증가시켜야합니다. 명백한 이유 때문에 void 포인터에서 산술 연산을 수행 할 수 없으므로 어떻게해야합니까? 던져. 그 점에는 아무런 부끄러운 것이 없습니다.

5

C++에서는 원시 바이트로 char *를 사용하고 자신보다 덜 생각하지 않습니다. 그것은 옳은 일 (tm)입니다. 특히 당신이 가지고있는 것 같은 고차원 구조로 포장한다면 말이죠.

+0

왜 downvote, 익명? 설명하고 정확하게 –

2

본질적으로 void *에 오류가있는 것은 없습니다. 그러나 우리가 종종 보는 것은 무언가를해야 할 때 void *를 과용하는 C에서 오는 사람들입니다. 원시 메모리 얼룩을 관리하는 경우 void *가 완벽하게 적합합니다. 그러나 거의 모든 다른 이유가 있습니다.

+0

+1을 수정하겠습니다. 관심 밖에서 '보이드 *를 과도하게 사용'하는 일반적인 방법은 무엇입니까? – JBRWilkinson

+0

void * 데이터, int 크기; memcpy (데이터, 버퍼, 크기); 템플릿 및 복사 생성자를 사용하는 대신 – Puppy

관련 문제