2010-07-31 50 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