4
 // move constructor ArrayWrapper (ArrayWrapper&& other) : _p_vals( other._p_vals ) , _size( other._size ) { other._p_vals = NULL; other._size = 0; } 

I found a tutorial on rvalue references. I don't really understand why we have to set other._p_vals = NULL; and other._size = 0; The author explains:

But why do we need to set other._p_vals = NULL? The reason is the destructor--when the temporary object goes out of scope, just like all other C++ objects, its destructor will run.

If it does go out of scope and gets destroyed why bother setting other._p_vals = NULL

When its destructor runs, it will free _p_vals. The same _p_vals that we just copied!

I thought we moved not copied, or... am I wrong?

If we don't set other._p_vals to NULL, the move would not really be a move--it would just be a copy that introduces a crash later on once we start using freed memory. This is the whole point of a move constructor: to avoid a copy by changing the original, temporary object!

Can someone help me understand?!?

1
  • The destructor would have code that does something to _p_vals (e.g. deletes it). If you do not have those lines, then you are actually copying and not moving. Commented Jan 6, 2017 at 8:32

1 Answer 1

4

Since this class contains a raw pointer, we can only assume it owns it, and therefore its destructor must look something like:

ArrayWrapper::~ArrayWrapper() { delete[] _p_vals; } 

In this move constructor we are "stealing" the internals of other. If we don't blank out the internals of other (being careful to leave it in a consistent "empty" state, so also setting _size = 0), then when either of other or the new object is destroyed, the one that remains will be pointing at some data that has now been deleted.

Sharing internals is a very different pattern to stealing someone else's internals.

Sign up to request clarification or add additional context in comments.

4 Comments

But isn't other a temporary object that will be destroyed anyways?
Not necessarily, but let's just suppose it is. Then other gets destroyed, and in its destructor (assuming it is properly written), deletes its _p_vals. Then the new object is pointing at garbage.
Thanks, it makes sense now!
And once other._p_vals has been set to NULL, other._size must be set to 0 otherwise the object would not be in a "valid" state.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.