class node
{
public:
node* next;
int val;
};
void func(node* root)
{
node* p=root->next;
delete p;
p=nullptr;
}
int main()
{
node* root=new node();
node* nxt=new node();
root->val=1;root->next=nxt;
nxt->val=2;nxt->next=nullptr;
func(root);
cout<<(nxt==nullptr)<<endl;//false
cout<<(root->next==nullptr)<<endl;//false
}
How can I modify the func()
to let last two line output 1?You can only delete nxt
through root
in func()
.
Edit:
At first I hold the thought that root->next
and nxt
are exactly one thing since root->next=nxt
.The fact is that root->next
is just a copy of nxt
.They have same value but are stored in different memory.In other words, they are two different pointer but point to the same memory where stores a node
with val==2
and next==nullptr
.Thus it's impossible to delete nxt
through root
.And the same mistake happened in func()
.
I modify the code to show the similarity and difference between root->next
and nxt
.
int main()
{
node* root=new node();
node* nxt=new node();
root->val=1;root->next=nxt;
nxt->val=2;nxt->next=nullptr;
//point to same memory
cout<<(root->next)<<endl;
cout<<(nxt)<<endl;
cout<<"---------"<<endl;
//stored in different memory
cout<<&(root->next)<<endl;
cout<<&nxt<<endl;
}
And get output like this:
0x7219b0
0x7219b0
---------
0x7219a0
0x61ff08
What's more,I find that root->next
subtract &(root->next)
is always 0x10
.In my opinion,the first value is where the node with val==2
is stored,the second value is a memory in the node with val==1
.I guess it's because the two node is allocated almost the same time,so the operating system allocate them in a contiguous segment of memory.
Hope this can help other beginner.
CodePudding user response:
In func()
, p
is its own unique variable. In your example, it holds a copy of the address held in root->next
. So, whatever you do to p
itself, will not effect root->next
in any way. However, when you are calling delete p
, you are destroying the Node
object that both p
and root->next
are pointing at. You are setting p
to nullptr
(which is redundant since p
goes out of scope immediately afterwards), but you are leaving root->next
dangling.
To fix func()
so that the (root->next==nullptr)
condition can become true in main()
, you have two choices:
get rid of
p
and just act onroot->next
directly:void func(node* root) { delete root->next; root->next = nullptr; }
make
p
be a reference toroot->next
rather than a copy:void func(node* root) { node* &p = root->next; delete p; p = nullptr; }
But, nothing that func()
does can affect the nxt
variable in main()
at all, since nxt
is local to main()
and func()
has no concept that nxt
exists. That is why the (nxt==nullptr)
condition can never become true in your example. In fact, the nxt
variable does not need to even exist at all, eg:
class node
{
public:
int val;
node* next = nullptr;
};
void func(node* root)
{
node* &p = root->next;
delete p;
p = nullptr;
}
int main()
{
node* root = new node{1};
root->next = new node{2};
func(root);
cout << (root->next == nullptr) << endl; // true
}