我已经实现了一个自定义分配器(由我的内存调试实用程序中的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);
}
}
这看起来非常混乱,但我看不出如何改进它。
答案 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);
}
}