Ada*_*hon 3 c++ pointers memory-management invalidation
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));
}
}
}
Run Code Online (Sandbox Code Playgroud)
正如您在评论中看到的那样,我忘了清除数组中的旧指针.当我第二次调用赋值运算符时,我得到glibc错误抱怨双重释放.提供的唯一信息是删除的地址.
这让我想到如何处理这类已删除的指针 - 当你不想再删除它们时,当你这样做时,肯定是一个错误.您不能将它们设置为NULL,因为另一个删除是正确的.您不希望保留该值,因为可以将内存位置分配给新创建的对象.
什么是适合调试是一些价值,如无效,对分配给这些指针说:"调用删除这个指针是一个错误",而不是NULL,它说"援引这个指针删除什么都不做".有这样的事吗?
不是.当你想拥有所有权语义时,更好的想法是不使用原始指针.如果您将类型设置为databe boost::ptr_vector<T>,std::vector<std::unique_ptr<T>>那么您将不必手动管理指针的生命周期,问题就会消失.
您的容器不能正确支持多态对象,因为您提供的赋值运算符会在将容器中的对象分配给另一个容器时对其进行切片.一个更好的解决方案可能就是拥有一个std::vector<T>.这只适用于你没有指望指针容器的其他属性(例如指向元素的指针的非失效,或者可能更快的排序操作).