使用分配器实例化对象的正确方法是什么?

时间:2009-08-18 15:59:13

标签: c++ memory

我已经实现了一个自定义分配器(由我的内存调试实用程序中的STL容器使用,没有它们使用我的重写的新运算符)。在内存调试器中,我使用相同分配器类的实例来分配我需要跟踪“正常”内存分配的对象。一切正常,但我不确定我使用分配器接口的方式是否正确。以下是它们当前的实用程序方法(很快就会添加正确的条目初始化参数):

iidebug::CMemoryDebugger::CEntry* iidebug::CMemoryDebugger::NewEntry()
{
    CEntry* pEntry = m_entryAllocator.allocate(1);
    if (0 != pEntry)
    {
        new(pEntry) CEntry(0, 0, __FILE__, 0, 0, 0);
    }
    return pEntry;
}

void iidebug::CMemoryDebugger::DeleteEntry( iidebug::CMemoryDebugger::CEntry* pEntry )
{
    if (0 != pEntry)
    {
        destruct(pEntry);
        m_entryAllocator.deallocate(pEntry, 1);
    }
}

这看起来非常混乱,但我看不出如何改进它。

3 个答案:

答案 0 :(得分:1)

你实际上可以重载new和delete来获取一个allocator参数,如下所示:

inline void *operator new(size_t sizeT, Allocator *&a) {
  return a->allocate(sizeT);
}

inline void operator delete(void * mem, Allocator *&a) {
  a->release(mem);
}

int main()
{
  Allocator * a = new Allocator;
  C *c = new(a) C;
  c->~C();
  operator delete(c, a);
  return 0;
}

有关详细信息,请参阅wikipedia article。它仍然有点乱,因为如果你的分配器做了一些特别的事情,你必须确保不要调用常规删除操作符。

答案 1 :(得分:1)

仅供参考以防任何人努力使用Drew的代码,它需要一些调整。以下是我最终使用的内容:

template <typename T>
void* operator new(SizeT iSize, SimpleAllocator<T>& rAllocator)
{
    return rAllocator.allocate(1);
}

template <typename T>
void operator delete(void* pvMemory, SimpleAllocator<T>& rAllocator)
{
    ((T*)pvMemory)->~T();   
    rAllocator.deallocate(pvMemory, 1);
}

实际使用它就像:

// SimpleAllocator<CFoo> fooAllocator = ...
CFoo* pFoo = new(fooAllocator) CFoo(param1, param2, ...); 
// Do stuff with pFoo...
operator delete(pFoo, fooAllocator);

答案 2 :(得分:0)

什么是destruct?我想它应该是:

void iidebug::CMemoryDebugger::DeleteEntry( iidebug::CMemoryDebugger::CEntry* pEntry )
{
    if (0 != pEntry)
    {
        pEntry->~CEntry();
        m_entryAllocator.deallocate(pEntry, 1);
    }
}