微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

移动运算符破坏原始指针

如何解决移动运算符破坏原始指针

我正在尝试使用指向内存位置的指针。 然后,如果我修改原始分配的变量 指向同一位置的人也必须受到变化的影响。

但是,问题是,有两个函数调用是在线发生的:

a = Data("New data");
  1. Data(const char* cdata) 构造函数调用
  2. Data operator=(Data&& data) 移动运算符被调用

编辑:我知道以下内容

  • std::shared_ptr
  • std::make_shared

但是,我试图在没有这些新功能的情况下实现这一点。我完全知道。

我的 C++ 代码

class Data 
{
private:
    char* local_data;
    int _size = 0;
    int length(const char* c)
    {
        int i = 0;
        while(c[++i] != '\0');
        return i;
    }
public:
    Data() {
        local_data = new char[_size];
    }
    
    Data(const char* cdata){
        _size = length(cdata);
        local_data = new char[_size];
        memcpy(local_data,cdata,_size);
    }
    
    int size() { return _size; }
    char* data() { return local_data; }
    const char* data() const { return local_data; }
    
    Data& operator=(const Data& data){}
    Data& operator=(Data&& data){
        
        if(this == &data)
            return *this;
        
        _size = std::move(data.size());
        local_data = std::move(data.data());
        return *this;
    }
};

int main(){
    
    Data a("Some data");
    auto dptr = a.data(); // Gives a pointer to the original location
    a = Data("New data"); // Must modify both a and dptr
    assert(dptr == a.data()); // Should pass successfully,else fail
    return 0;
}

解决方法

您似乎想要std::shared_ptr<std::string>

class Data 
{
private:
    std::shared_ptr<std::string> local_data = std::make_shared<std::string>();
public:
    Data() = default;
    
    Data(const char* cdata) : local_data(std::make_shared<std::string>(cdata)) {}
    
    int size() const { return local_data->size(); }
    char* data() { return local_data->data(); }
    const char* data() const { return local_data->c_str(); }
    
    Data operator=(const Data& rhs) {
        if (this == &data)
            return *this;
        
        *local_data = *rhs.local_data;
        return *this;
    }
};

int main(){
    
    Data a("Some data");
    auto dptr = a.data(); // Gives a pointer to the original location
    a = Data("New data"); // Must modify both a and dptr
    assert(dptr == a.data()); // Should pass successfully
}
,

您的 class Data 存在一些问题。首先,它从不调用 delete[] local_data,因此会泄漏内存。添加析构函数:

~Data() {
    delete[] local_data;
}

然后确保您的移动赋值运算符正常工作。不要使用std::move(data.data()),这实际上不会设置从移动到nullptr 的对象中的指针。此外,请确保正确清理 this->local_data。最简单的方法是:

Data& operator=(Data&& data){
    std::swap(local_data,data.local_data);
    std::swap(_size,data._size);
    return *this;
}

它交换了指针,所以没有内存泄漏。移动后,销毁 data 将确保删除旧的 this->local_data

你的复制赋值运算符是空的,你应该解决这个问题,如果你有一个移动赋值运算符,你可能还想实现一个移动构造函数。最后:

assert(dptr == a.data()); // Should pass successfully,else fail

这是错误的; dptr 不应与 a.data() 相同,因为 dptr 是指向移动分配之前获取的数据的指针的副本。除非您明确修改 dptr,否则 dptr 的值不会改变。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。