Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/137.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 移动运算符销毁原始指针_C++_C++11 - Fatal编程技术网

C++ 移动运算符销毁原始指针

C++ 移动运算符销毁原始指针,c++,c++11,C++,C++11,我正在尝试使用指向内存位置的指针。 然后,如果我修改了原始的变量 指向同一位置的用户也必须受到更改的影响 但是,问题是,有两个函数调用是在线进行的: a = Data("New data"); Data(const char*cdata)调用构造函数 Data操作符=(Data&&Data)move操作符被调用 编辑:我知道以下几点: std::共享\u ptr std::使_共享 但是,我正试图在没有这些新特性的情况下实现这一点。我完全知道 我的C++代码:< /强

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

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

a = Data("New data");
  • Data(const char*cdata)
    调用构造函数
  • Data操作符=(Data&&Data)
    move操作符被调用
  • 编辑:我知道以下几点:

    • std::共享\u ptr
    • std::使_共享
    但是,我正试图在没有这些新特性的情况下实现这一点。我完全知道

    <强>我的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\u ptr

    类数据
    {
    私人:
    std::shared_ptr local_data=std::make_shared();
    公众:
    Data()=默认值;
    数据(const char*cdata):本地数据(std::make_shared(cdata)){}
    int size()常量{return local_data->size();}
    char*data(){return local_data->data();}
    const char*data()const{return local_data->c_str();}
    数据运算符=(常量数据和rhs){
    如果(此==&数据)
    归还*这个;
    *本地_数据=*rhs.local_数据;
    归还*这个;
    }
    };
    int main(){
    数据a(“某些数据”);
    auto dptr=a.data();//给出指向原始位置的指针
    a=数据(“新数据”);//必须同时修改a和dptr
    assert(dptr==a.data());//应成功传递
    }
    
    您的
    类数据存在一些问题。首先,它从不调用
    delete[]local\u data
    ,因此会泄漏内存。添加析构函数:

    ~Data() {
        delete[] local_data;
    }
    
    然后确保移动分配操作符正常工作。不要使用
    std::move(data.data())
    ,这实际上不会在从移动到
    nullptr的对象中设置指针。此外,请确保正确清理
    此->本地\u数据。最简单的方法是:

    Data& operator=(Data&& data){
        std::swap(local_data, data.local_data);
        std::swap(_size, data._size);
        return *this;
    }
    
    它交换指针,因此没有内存泄漏。移动后,销毁
    数据
    将确保删除旧的
    this->local_数据

    您的复制分配运算符为空,您应该修复该问题,如果您有移动分配运算符,您可能还希望实现移动构造函数。最后:

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

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

    始终为
    0
    ,否则
    dptr的值不会更改,因此您始终分配0字节并复制0字节。此处的
    \u size
    部分无关。自动取款机。与此相关的是
    移动操作符
    “必须同时修改a和dptr”-这在移动语义中是不会发生的
    dptr
    是一个普通的
    const char*
    。您的移动分配操作符实际上是用一个不同的值替换作为
    local\u data
    保存的指针。我甚至不想尝试去理解你到底想做什么,但有一种方法可以(非常值得怀疑)做到这一点,那就是让
    data()
    返回
    const char*&
    (即,对成员的引用,而不是其值的副本。请注意;这是一个可怕的想法,也是一个悬空引用的诀窍。@WhozCraig,谢谢。我不希望悬空指针或内存泄漏。此处的_大小部分无关紧要。“,因此不要将其包含在M(最小值)中)CVE.Hi Jarod42,thx。我不想在这里使用它,
    std::shared\u ptr
    。但是,我完全知道。让我更仔细地看看你在做什么。没有,
    std::make\u shared
    。如何以常规方式实现这一点?常规方式是使用std:)我甚至认为
    std::unique\u ptr
    就足够了(如果你不能使用std,重写就更简单。)Jarod,但没有它。如果你不能使用std,写你自己的(简化)如果您不知道如何编写等价于
    std::string
    /
    std::unique\u ptr
    /
    std::vector
    ,请进行搜索,然后询问相关的具体问题。
    assert(dptr == a.data()); // Should pass successfully, else fail