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));
}
}
}
コメントでわかるように、配列内の古いポインターを消去するのを忘れていました。代入演算子を 2 回目に呼び出したとき、ダブル フリーについて不平を言う glibc エラーが発生しました。提供された唯一の情報は、削除された住所でした。
これは、そのような削除されたポインターのクラスをどうするかについて考えさせます-それらを再度削除したくない場合、および削除した場合、それは確かにエラーです。別の削除が正しいため、それらを NULL に設定することはできません。新しく作成されたオブジェクトにメモリの場所を割り当てることができるため、値を保持したくありません。
デバッグに適しているのは、INVALID などの値です。これらのポインターに割り当てる値は、「このポインターで delete を呼び出しても何も起こらない」という NULL の代わりに、「このポインターで delete を呼び出すとエラーです」と表示されます。このようなものはありますか?