Reputation:
I am trying to have a pointer to a memory location. Then, if I modify the original the assigned variable who points to the same location must be also affected by the change.
But, the thing is, there are two function calls, that happen on line:
a = Data("New data");
Data(const char* cdata)
constructor is called.Data operator=(Data&& data)
move operator is called.EDIT: I am aware of the folloing:
but, I am trying to accomplish this without these new features. I am fully aware.
My C++ code:
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;
}
Upvotes: 1
Views: 221
Reputation: 7973
There are a few issues with your class Data
. First, it never calls delete[] local_data
, so it will leak memory. Add a destructor:
~Data() {
delete[] local_data;
}
Then ensure your move assignment operator works correctly. Don't use std::move(data.data())
, this does not in fact set the pointer in the object that is moved from to nullptr
. Also, ensure you clean up this->local_data
properly. The easiest way to do this is:
Data& operator=(Data&& data){
std::swap(local_data, data.local_data);
std::swap(_size, data._size);
return *this;
}
It swaps the pointers around, so there is no memory leak. After the move, the destruction of data
will ensure the old this->local_data
is deleted.
Your copy assignment operator is empty, you should fix that, and if you have a move assignment operator you probably also want to implement a move constructor. Finally:
assert(dptr == a.data()); // Should pass successfully, else fail
This is wrong; dptr
should not be the same as a.data()
, since dptr
is a copy of the pointer to the data taken from before the move assignment. The value of dptr
will not change unless you explicitly modify dptr
.
Upvotes: 0
Reputation: 217478
It seems you want 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
}
Upvotes: 2