c++ - 使已删除的指针无效?

标签 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));
        }
    }
}

如您在评论中所见,我忘记清除数组中的旧指针。当我第二次调用赋值运算符时,出现 glibc 错误,提示双重释放。提供的唯一信息是已删除的地址。

这让我思考如何处理此类已删除的指针 - 当您不想再次删除它们时,当您这样做时,这肯定是一个错误。您不能将它们设置为 NULL,因为另一个删除将是正确的。您不想保留该值,因为可以将内存位置分配给新创建的对象。

对调试有好处的是一些值,比如 INVALID,你分配给这些指针说“在这个指针上调用 delete 是一个错误”,而不是 NULL,它说“在这个指针上调用 delete 什么都不做”。有这样的吗?

最佳答案

没有。当您想要拥有所有权语义时,一个更好的主意是不使用原始指针。如果您将类型设为 databoost::ptr_vector<T>std::vector<std::unique_ptr<T>>那么您就不必手动管理指针的生命周期,问题就会消失。

您的容器不支持多态对象,因为您提供的赋值运算符会在容器中的对象分配给另一个容器时对其进行切片。一个更好的解决方案可能是只拥有一个 std::vector<T> .这仅在您不依赖指针容器的某些其他属性(例如指向元素的指针的非无效性,或可能更快的排序操作)时才适用。

关于c++ - 使已删除的指针无效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7722972/

相关文章:

c++ - 在循环迭代期间在 vector 中保存对 void 指针的引用

c - Memcpy 到 malloced 结构内的数组中

iphone - 多线程 iPhone 应用程序因 [NSAutoreleasePool release] 崩溃

C++ vector 构造函数和赋值问题

c++ - 在我的类 C++ 中创建一个对象

c++ - 为什么这里没有省略复制构造函数?

c - 抽象出这个过程是否值得?

c++ - Eclipse CDT 提示 Unresolved 功能,但仍然成功构建

C++:array1 = array2 vs使用循环将array2的值分配给array1

javascript - node.removeChild(node.firstChild) 是否会造成内存泄漏?