Моя ставка заключается в том, что не только некоторые значения появляются более одного раза, некоторые отдельные объекты появляются более одного раза в последовательности.
Когда вы delete
все дублируете значения, вы уничтожаете некоторые объекты, которые остаются в последовательности.
Второй вид (который не нужен, так как unique
не переставляет вещи, так как удаляет дубликаты) обращается к каждому объекту, поэтому он немедленно наступает на те, которые были просто delete
d.
Одним из возможных решений является sort
указатели в обоих диапазонах, следующие из unique
. Используйте set_difference( i_new_end, it_end, i_begin, i_new_end, i_sequence_inserter )
, чтобы найти объекты, которые действительно должны быть освобождены - при условии, что они больше нигде не используются.
Или просто используйте умные указатели или вообще не указывайте: v).
Edit:
См. Мой комментарий - лучшее решение, вероятно, полностью исключит использование указателей.
В любом случае, вот пример решения set_difference
, в котором используется пользовательский итератор вместо средства вставки последовательности.
template <typename Item>
template <typename Sort, typename Equal>
void Container <Item * >::remove ( typename TList <Item *>::Type ::iterator it_begin, typename TList <Item *>::Type ::iterator it_end, Sort sort, Equal equal )
{ //Sort items, ok
std::sort ( it_begin, it_end, sort );
//Apply unique, OK
typename TList <Item *>::Type ::iterator i_new_end = std::unique ( it_begin, it_end, equal );
// Now sort the sub-ranges on pointer values to identify duplicate pointers
std::sort( it_begin, i_new_end );
std::sort( i_new_end, it_end );
// delete all pointers that appear only in the set of duplicate values to be erased
struct deleter {
deleter &operator *() { return *this; } // assignment to target is assgn. to iter
deleter &operator =( Item *rhs ) { delete rhs; return *this; }
deleter &operator ++() { return *this; } // increment is no-op
deleter &operator ++(int) { return *this; } // increment is no-op
};
std::set_difference( i_new_end, it_end, it_begin, i_new_end, deleter() );
//Erase duplicate items
this->items.erase ( i_new_end, it_end );
//Another sort, Exception: Acces in free memory
std::sort ( it_begin, i_new_end, sort );
);