2012-03-11 3 views
1

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? 
    } 
} 

ответ

2

Как можно заметить, что ваш код утечка памяти будет и uninitialized_copy должен содержаться в try/catch блок сам. Вся цель Повторное выбрасывание исключения внутри функции копирования так что можно атомарно сигнал о том, что операция копирования не удалось, так что код окружающей среды может выполнять свою собственную очистку:

T* newmem = alloc.allocate (size); 
try { /* copy, reassign pointer, free previous */ } 
catch (...) { alloc.deallocate(newmem); throw; } 
+0

Предполагая, что C++ 11, я бы использовал здесь 'unique_ptr', а не' try/catch', но это только я. – ildjarn

+0

@ildjarn: Уникальный указатель на * what *? Мы создаем последовательность последовательных объектов 'T', построенных здесь. 'Unique_ptr ' возможно? –

+0

'unique_ptr ' с пользовательским удалением; является RAII не более разумным, чем 'try/catch'? – ildjarn

0

запустить его через Valgrind тоже. Если у него есть утечки, Valgrind, скорее всего, найдет их.