简体   繁体   中英

confusion about struct pointer C++

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

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 (ie, 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:

在此处输入图片说明

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.

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

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM