Reputation: 9347
Consider the following code snippet:
fn main() {
let mut v1 = vec![1, 2, 3];
println!("The address of vector v1 is {:p}", &v1);
let v2 = v1;
println!("The address of vector v2 is {:p}", &v2);
v1 = v2;
println!("The address of vector v1 is {:p}", &v1);
}
and the output
The address of vector v1 is 0x7fff253de570
The address of vector v2 is 0x7fff253de5e0
The address of vector v1 is 0x7fff253de570
Why does the value of v1
and v2
not the same?
&v2
really mean the address of vector vec![1,2,3]
as declared in line #2?v1
is copied to v2
then, should not the vector have a copy trait?v1
is moved to a new memory location which is identified by v2
, why is it at all required, why doesn't the v2
simply point to the memory location of v1
, because the ownership is already transferred to v2
, and v1
is pretty much useless until I assign it back (in short, if it is a memory copy, why does the ownership transfer require a memcpy
?)v1
is assigned to v2
again, how did I get the same address location?Upvotes: 3
Views: 433
Reputation: 23264
You're confusing the address of the data and the address of the variable. In the beginning, your memory looks something like this:
Stack Heap
+----+------+---+ +---+---+---+
| | len | 3 | +-->| 1 | 2 | 3 |
| v1 +------+---+ | +---+---+---+
| | data |---+
+----+------+---+
| | len | _ |
| v2 +------+---+
| | data |
+----+----------+
After you do let v2 = v1
, it looks like this:
Stack Heap
+----+------+---+ +---+---+---+
| | len | _ | +-->| 1 | 2 | 3 |
| v1 +------+---+ | +---+---+---+
| | data | |
+----+------+---+ |
| | len | 3 | |
| v2 +------+---+ |
| | data |---+
+----+----------+
Note that the locations of v1
and v2
have not changed, and neither has the location of the data on the heap, but the values of the fields of v1
have been moved into v2
. At that point, the values of the fields of v1
are invalid.
Then when you do v1 = v2
, you go back to the first configuration.
OTOH your println
statements print the address of the variables v1
and v2
on the stack.
Note that if you print &v1[0]
(resp. &v2[0]
), you will get the address of the data on the heap and see that it doesn't change (playground)
Upvotes: 5
Reputation: 26066
Why does the value of
v1
andv2
not the same?
Why would it be the same? They are different variables in the stack.
What is the same is the storage in the heap.
- First, Doesn't
&v2
really mean the address of vectorvec![1,2,3]
as declared in line #2?
No, it means borrowing v2
. What you see is {:p}
being implemented for references which prints their address.
- If the value of
v1
is copied tov2
then, should not the vector have a copy trait?
No, in most cases you do not want to allocate memory in the heap and copy it.
- If the value of
v1
is moved to a new memory location which is identified byv2
, why is it at all required, why doesn't thev2
simply point to the memory location ofv1
, because the ownership is already transferred tov2
, andv1
is pretty much useless until I assign it back (in short, if it is a memory copy, why does the ownership transfer require amemcpy
?)
That is what actually occurs. It is a move, so only the bits of the vectors are copied, not the contents in the heap.
- When
v1
is assigned tov2
again, how did I get the same address location?
Why would it be different? It is still the same palce in the stack.
Upvotes: 2
Reputation: 15772
&v2
is a reference to v2
, not the address of v2
.v2
is not a copy of v1
, it is a "move", but since it is the same scope, nothing really happens.v1
is now the moved value of v2
, again same scope, so the same address can be reused.Upvotes: -3