Josuttis展示了一个关于可能的分配器使用的例子(第15章):
void vector<T,Allocator>::reserve(size_type size)
{
//allocate new memory for size elements
T* newmem = alloc.allocate (size);
//copy old elements into new memory
uninitialized_copy(elems,elems+numElems,newmem);
如果uninitialized_copy失败会怎样?是否有任何内存泄漏或被::operator delete
神奇地调用(请参阅下面代码中的注释):
template <class InputIter, class ForwIter>
ForwIter uninitialized_copy(lnputIter beg, InputIter end, ForwIter dest)
{
typedef typename iterator_traits<ForwIter>::value_type VT;
ForwIter save(dest);
try {
for (; beg!=end; ++beg,++dest) {
new (static_cast<void*>(&*dest))VT(*beg);
}
return dest;
}
catch (...) {
for (; save!=dest; ++save) {
save->~VT();
}
throw; // will ::operator delete() be called to free the previously allocated memory?
}
}
答案 0 :(得分:2)
目前,您的代码将泄漏内存,而uninitialized_copy
必须包含在try
/ catch
块中。在复制函数中重新抛出异常的全部目的是为了能够原子地通知复制操作失败,以便环境代码可以执行自己的清理:
T* newmem = alloc.allocate (size);
try { /* copy, reassign pointer, free previous */ }
catch (...) { alloc.deallocate(newmem); throw; }
答案 1 :(得分:0)
也通过valgrind运行它。如果它有泄漏,Valgrind也可能会发现它们。