2009-08-18 54 views
1

我已经实现了一个自定义分配器(由我的内存调试工具中的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); 
    } 
} 

这只是似乎很凌乱,但我看不到我如何能够改善它。

回答

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。它仍然有点麻烦,因为如果你的分配器做了一些特殊的事情,你必须确保不要调用常规的删除操作符。

+0

这是一个更简洁的选项,谢谢:) – FlintZA 2009-08-19 05:22:58

+1

我喜欢做的事情也是重写默认的new运算符,以便所有分配在分配头部有一个函数指针(如果在32位x86应用程序上工作,需要添加额外的4个字节),该指针指向函数dealloc吃了记忆。那么当你删除对象时(所有的对象都可以通过默认的删除操作符删除),你只需调用该函数指针即可。 – 2009-08-19 06:45:16

+0

有趣的想法是,这是为了内存调试吗?如果它处于默认的new中,并且总是传入相同的函数指针,那么为什么不直接在重写的delete内部调用该函数,而不是在每个指针上占用额外的4个字节? – FlintZA 2009-08-19 16:23:37

0

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

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

比较遗憾的是,毁灭是实现为处理销毁在HTTP 3个辅助功能之一: //www.codeguru.com/cpp/cpp/cpp_mfc/stl/article.php/c4079 – FlintZA 2009-08-19 05:26:13

1

仅供参考,以防万一任何人使用德鲁的代码,它需要一些调整。下面是我最终使用:

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); 
相关问题