Reputation: 103
In the code shown below, func(a3)
enters the if condition and produces output "hi". However, different behavior is observed when the parameter to the function is an expression.
For example, func(a1->right)
doesn't enter the if condition.
#include <iostream>
using namespace std;
class Node {
public:
int data;
Node *left, *right, *parent;
public:
Node(int data) : data(data) {
left = nullptr;
right = nullptr;
parent = nullptr;
}
~Node() {}
};
void func(Node*& node) {
Node* p = node->parent;
p->right = node->left;
if (node->left) {
cout << "hi\n";
node->left->parent = p;
}
node->parent = p->parent;
}
int main() {
Node* a1 = new Node(10);
Node* a2 = new Node(20);
Node* a3 = new Node(30);
Node* a4 = new Node(40);
Node* a5 = new Node(50);
a1->left = a2; a2->parent = a1;
a1->right = a3; a3->parent = a1;
a3->left = a4; a4->parent = a3;
a3->right = a5; a5->parent = a3;
/*
a1
/ \
a2 a3
/ \
a4 a5
*/
/* Case 1: prints hi */
func(a3);
/* Case 2: doesn't print hi */
// func(a1->right);
/* Case 3: prints hi */
// Node* ptr = a1->right;
// func(ptr);
}
I have two questions:
Reason for different behavior when reference of expression is passed to func as opposed to reference of a variable?
What is idiomatic way of passing reference of an expression to a function.
Edit: gdb output
(gdb) b 17
Breakpoint 1 at 0x555555554856: file pointer_ref.cpp, line 17.
(gdb) r
Starting program: /home/a.out
Breakpoint 1, func (node=@0x555555767e80: 0x555555767ed0) at pointer_ref.cpp:18
18 Node* p = node->parent;
(gdb) p node->data
$1 = 30 // a3
(gdb) n
19 p->right = node->left;
(gdb) p p->data
$2 = 10 // a1
(gdb) n
20 if (node->left) {
(gdb) p p->right->data
$3 = 40 // a4
**(gdb) p node->left->data
Cannot access memory at address 0x0**
// ^^^ This seems to be the problem location
// After changing p->right to node->left,
// somehow, node->left becomes null
(gdb) p node->left
$4 = (Node *) 0x0
(gdb)
Upvotes: 0
Views: 198
Reputation: 44278
Reason for different behavior when reference of expression is passed to func as opposed to reference of a variable?
Reason is the convoluted logic you have in your program. In this particular case when you either pass a3
or a1->right
either pointer points to the same object, but func()
itself modifies a1->right
so when reference to a3
passed that changes does not affect node
but when a1->right
passed it does. Hense the difference.
What is idiomatic way of passing reference of an expression to a function.
There is no problem of passing reference the way you do, problem is overcomplicated data relationship. For example in your case there is no reason to pass this pointer by reference.
Upvotes: 0
Reputation: 990
You have passed reference to a1->right
. So any changes you make to that field are seen in that function. The p->right = node->left;
actually sets a1->right
to a different node.
In the case 3, you pass reference to a local variable ptr
, which does not get changed, since it is a copy.
If you add:
cout << "node was " << node << std::endl;
p->right = node->left;
cout << "node is " << node << std::endl;
You will see that your node changes.
Upvotes: 1