Reputation: 2317
I wrote the following piece of code. I have a question: in these two line:
r1 = r;
r1 = new node();
I think that when r1
becomes a new empty node, r
should also be a new empty node because r1=r
is a pointer assignment, so r1
and r
represent the same address. However I must be wrong because the result shows that r
here was not changed. Could anybody explain it to me why r
is not changed? Thank you.
#include<iostream>
using namespace std;
struct node{
int id;
node *child;
};
int main()
{
node *r = new node();
node *r1 = new node();
r->id = 100;
r1 = r;
r1 = new node();
r1->child = r;
cout << "r1 " << r1->id << endl;
cout << "r1 child " << (r1->child)->id << endl;
}
Result:
r1 0
r1 child 100
Upvotes: 0
Views: 83
Reputation: 33982
Marching through the code step by step may help explain what is happening.
node *r = new node();
Create block of memory A and point r
at A
node *r1 = new node();
Create block of memory B and point r1
at B
r->id = 100;
Dereference r
to locate A. id
in A is set to 100
r1 = r;
Point r1
at the same thing as r
. r1
now points to A. There is no linkage between A and B. Nothing is copied from A to B. r1
is merely redirected to point A instead of B.
B no longer has any referrers and is lost. This is called a memory leak. delete r1;
before reassigning to prevent this. Better, since B is never used, don't allocate it in the first place.
r1 = new node();
Create block of memory C and point r1
at C. As above, r1
is directed to point at C instead of A. No copying or other side effects take place. There is no longer any association between r1
and A. A is unchanged and r
still points at A.
r1->child = r;
Dereference r1
to locate C. Point child
in C at A.
cout << "r1 " << r1->id << endl;
Dereference r1
to locate C. Print out id
in C. id
in C has never been assigned a value, so using it is undefined behaviour. Any value may be printed, nothing may be printed, or the program may cause the computer to grow legs and eat the neighbour's cat, though this is unlikely.
cout << "r1 child " << (r1->child)->id << endl;
Dereference r1
to locate C. Dereference child
in C to locate A. Print out id
in A, 100.
Upvotes: 0
Reputation: 490663
A pointer is exactly that, a pointer--it points (refers to) something else.
I think in this case, it's probably easiest to understand things graphically. So, after you do:
node *r = new node();
node *r1 = new node();
r->id = 100;
The situation is roughly like this:
Then when you execute: r1 = r;
, you get a situation like this:
Note that you've leaked the node
that r1
was pointing to (i.e., you no longer have a pointer to it, so you can't delete it any more).
Then when you do r1 = new node();
: you get something like this:
Finally, after executing r1->child = r;
you have something like this:
Upvotes: 3
Reputation: 181027
I have a question: in these two line:
r1 = r;r1 = new node();
I think that whenr1
becomes a new empty node,r
should also be a new empty node becauser1=r
is a pointer assignment
Nope. When you do r1 = r;
all you are doing is setting the value of r1
to the same value of r
. It does not link r1
and r
together and anything you change in r1
to does nothing to r
.
You should also note that r1 = r;
causes a memory leak as r1
no longer points to the node you originally created and you did not delete
it before the assignment.
Upvotes: 0
Reputation: 2172
They cannot be the same. r
and r1
are two locations in the memory which can hold address to node
(by definition in the code), so when you perform r1 = r
, the value in those memory locations become the same (pointer value).
But, when you later perform r1 = new node;
then the new
returns a pointer to the newly created object, which is only stored in r1
memory location. Since address in r
location in the memory does not change, hence you see the results.
Upvotes: 0