template<typename T>
someclass<T>& operator=(const someclass<T>& other)
{
typename std::vector<T *>::const_iterator rhs;
typename std::vector<T *>::iterator lhs;
//identity test
//this->data is std::vector<T *>
for(lhs = this->data.begin(); lhs != this->data.end(); lhs++)
{
delete *lhs;
}
this->data.clear(); // this is what I forgot
this->data.reserve(other.data.size());
for (rhs = other.data.begin(); rhs != other.data.end(); rhs++)
{
if (NULL == *rhs)
{
this->data.push_back(NULL);
}
else
{
this->data.push_back(new T(**rhs));
}
}
}
Как вы можете видеть в комментариях, я забыл очистить старые указатели в массиве. Когда я во второй раз вызвал оператор присваивания, я получил ошибку glibc с жалобой на двойное освобождение. Единственной предоставленной информацией был удаленный адрес.
Это заставляет меня задуматься о том, что делать с таким классом удаленных указателей - когда вы не хотите удалять их снова и когда вы это делаете, это, безусловно, ошибка. Вы не можете установить их в NULL, потому что тогда другое удаление будет правильным. Вы не хотите сохранять значение, так как ячейка памяти может быть назначена вновь созданному объекту.
Что было бы хорошо для отладки, так это какое-то значение, например INVALID, которое вы присваиваете этим указателям, говоря «вызов удаления для этого указателя - ошибка» вместо NULL, который говорит «вызов удаления для этого указателя ничего не делает». Есть ли что-то подобное?