2010-07-31 46 views
6

我想實現一個自定義的內存管理器,我想知道是否有更好的方法來實現這個功能,因爲當我被問及無效指針算術時,幾個人認爲,如果我有一個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 *,有些東西是非常錯誤的。」 < - 我不會同意這一點。無效指針有其用途。我想這歸結於你是否是'反C'C++社區的一部分,或者不是。我傾向於說,雖然是的,C++是比C更高級別的語言,但人們通常會在其中做低級別的事情,所以使用其更類似C的功能沒有任何問題。 – Stephen 2010-07-31 12:31:14

+2

@Stephen:爲什麼這麼多程序員有這種膝蓋反射,當一個概念受到批評時,他們只會*說「這不是邪惡的,它有它的用處」。我想你對單身和gotos也一樣。但在這種情況下,void *有什麼用途?他爲什麼要在這裏使用void *? – jalf 2010-07-31 12:59:53

+1

@Jalf因爲負面評論在人們的頭腦中的含義遠遠超過正面評論。這意味着,如果某個剛剛接觸編程的人或者之前沒有聽說過X的人閱讀了一篇評論,指出X不應該使用它,他們很可能會將這些知識視爲他們的頭腦中的事實。另外,我只是在陳述意見。如果我已經備份了「不使用void指針」視圖,你會回答嗎?這裏沒有,沒有理由使用它,但是OP只是說人們告訴他在編寫C++時不要使用它們。 – Stephen 2010-07-31 13:14:35

回答

7

如果您需要用於存儲字符串(8位ANSI)的內存塊,將char指針指定爲char並對其進行操作是有意義的。

在你的情況下,你需要一塊「blob」的內存塊,它沒有固有的類型,所以你正確地選擇了void *來表示該blob。

現在您需要通過某個對象的大小增加該指針。出於顯而易見的原因,你不能在void指針上執行算術,所以你做了什麼?投它。這不是什麼恥辱。

5

在C++中,對於原始字節,使用char *,並且不要以爲自己就更少。這是正確的事情要做(tm)。特別是如果你把它包裝在更高層次的構造中,就像你擁有的一樣。

+0

爲什麼downvote,匿名?解釋一下,我會更正 – 2012-10-02 19:05:34

2

void *沒有任何內在的錯誤。但是,我們經常看到的是來自C的人在他們應該做其他事情時過度使用無效*。如果你正在管理原始內存blob,那麼void *是完全合適的。但是,很少有其他理由要這樣做。

+0

+1。出於興趣,「過度使用空白」的典型方法是什麼? – JBRWilkinson 2010-07-31 14:51:00

+0

void * data,int size; memcpy(數據,緩衝區,大小);而不是使用模板和複製構造函數。 – Puppy 2010-07-31 17:01:45