使已删除的指针失效
Invalidating deleted pointers?
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错误,抱怨double free。提供的唯一信息是被删除的地址。
这让我思考如何处理这类被删除的指针——当你不想再次删除它们时,当你这样做时,这肯定是一个错误。您不能将它们设置为NULL,因为另一次删除将是正确的。您不希望保留该值,因为内存位置可以分配给新创建的对象。
对调试有好处的是一些值,比如INVALID,你把它赋给这些指针,说"在这个指针上调用delete是一个错误",而不是NULL,说"在这个指针上调用delete什么也不做"。有这样的东西吗?
No。一个更好的主意是,当您希望拥有所有权语义时,不要使用原始指针。如果您将data
的类型设置为boost::ptr_vector<T>
或std::vector<std::unique_ptr<T>>
,那么您将不必手动管理指针的生命周期,并且问题将解决。
您的容器不支持多态对象,因为您所提供的赋值操作符将在容器中的对象分配给另一个容器时对其进行切片。更好的解决方案可能是只使用std::vector<T>
。只有当您不考虑指针容器的其他属性(例如指向元素的指针的非无效性,或者可能更快的排序操作)时,这才合适。
解决这个问题的方法是编写不包含任何删除的代码。尽可能使用shared_ptr
。当你有一个拥有多态对象的容器时,你也可以使用指针容器。
相关文章:
- 1d 智能指针不适用于语法 (*)++
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 为什么使用 "this" 指针调用派生成员函数?
- 函数向量_指针有不同的原型,我可以构建一个吗
- 使用指针从C++中的数组中获取最大值
- 助记符和指向成员语法的指针
- 嵌入方指针压缩已禁用
- 不明白迭代器,引用和指针失效,一个例子
- C++,您能否设计一种数据结构,将指针保存在连续内存中并且不会使它们失效?
- std::unordered_map::提取引用/指针失效
- std::vector, std::move 和指针失效
- 如果我不使用 vector.reserve(),为什么我的指针会失效?
- 调整窗口内存映射文件的大小,而不会使指针失效
- 指向已销毁类失效的指针
- 迭代器与指针(引用)的双插入失效
- 为什么共享指针在修改后要失效
- 如果STL容器中的迭代器失效,指针是否也会失效?
- 使用pop_back时防止指针失效
- 使已删除的指针失效
- 如何在不使指向它的指针失效的情况下增长缓冲区