Reputation: 127
I am trying to grasp the concept of move semantics, rvalues, lvalues in c++ and am facing a problem. I am first looking at this popular answer - https://stackoverflow.com/a/3109981/9576161
I wrote a small program based on that reply to understand what is going on. I am using g++
(on linux) and the -fno-elide-constructors
for compiling without rvalue optimization by the compiler.
Here is the small program:
#include <iostream>
#include <cstring>
using namespace std;
class string {
public:
char* data;
string (const char* p) {
cout << "Constructor 1 called\n";
size_t size = strlen(p) + 1;
data = new char[size];
cout << "this location is: " << this << endl;
memcpy (data,p,size);
}
string (string&& that) {
cout << "Constructor 2 called\n";
//cout << "data is " << data << " data location is: " << &data << endl;
cout << "data location is: " << &data << endl;
cout << "that.data is " << that.data << " that.data location is: " << &that.data << endl;
data = that.data;
that.data = nullptr;
cout << "this location is: " << this << " data is: " << data << endl;
cout << "data location is: " << &data << endl;
cout << "that.data location is: " << &that.data << endl;
}
~string() {
delete[] data;
cout << "Destructor called for object located at: " << this << endl;
}
void print() {
cout << "String is: " << data << endl;
}
};
int main () {
::string R = "12345";
cout << "R constructed and located at: " << &R << endl << endl;
return 0;
}
On running the program, I see the following result:
ubuntu@thinkpad:~/programming_practice/c_projects$ g++ -fno-elide-constructors move_semantics_short.cpp
ubuntu@thinkpad:~/programming_practice/c_projects$ ./a.out
Constructor 1 called
this location is: 0x7fffac01bb80
Constructor 2 called
data location is: 0x7fffac01bb78
that.data is 12345 that.data location is: 0x7fffac01bb80
this location is: 0x7fffac01bb78 data is: 12345
data location is: 0x7fffac01bb78
that.data location is: 0x7fffac01bb80
Destructor called for object located at: 0x7fffac01bb80
R constructed and located at: 0x7fffac01bb78
Destructor called for object located at: 0x7fffac01bb78
ubuntu@thinkpad:~/programming_practice/c_projects$
Notice the line data = that.data
in the second constructor (where it says "Constructor 2 is called"). What does it do? Aren't data
and that.data
both character pointers? Why is data
not changing in value? Shouldn't data
now equal the value of that.data
which is 0x7fffac01bb80
? Instead it seems like some kind of memcopy
is occurring and the character string that that.data
points to is now pointed to by data
. Any hints on what is going on would be helpful.
Upvotes: 0
Views: 87
Reputation: 30639
The type of &data
is char**
. That is, it's the memory location of the pointer that stores the memory location of some char
.
data = that.data;
does not make &data
equal &that.data
. It just makes data
and that.data
equal. They now point to the same char
, but they each exist independently in memory.
If instead of printing data
's address, you print the address stored in data
, you can see that you are stealing the array of char
s that was owned by that
in your move constructor.
Upvotes: 2