Passing Pointers by Reference
Understand Mainly - Passing Pointers
Basics
Section titled “Basics”What is a Pointer?
Section titled “What is a Pointer?”A pointer is a variable that stores the address of another variable/object.
TreeNode* root;Here:
-
root→ Pointer variable -
*root→ TheTreeNodeobject -
root->valis equivalent to(*root).val
Example:
TreeNode node;TreeNode* root = &node;Memory:
node+-------+| val=5 |+-------+ ^ |root (stores address of node)Variables are Passed by Value by Default
Section titled “Variables are Passed by Value by Default”Every variable in C++ is passed by value unless you explicitly use &.
Example:
void func(int x) { x = 10;}
int a = 5;func(a);Memory:
Caller Function
a = 5 x = 5 (copy)Changing x doesn’t change a.
Passing by Reference
Section titled “Passing by Reference”void func(int& x) { x = 10;}Memory:
a = 5
x ----> aNo copy is created.
x is another name (alias) for a.
Changing x changes a.
A Pointer is Also a Variable
Section titled “A Pointer is Also a Variable”This is the most important concept.
TreeNode* root;root is not the tree.
root is just a variable whose value is an address.
Like any other variable, it can also be:
-
passed by value
-
passed by reference
Passing a Pointer by Value
Section titled “Passing a Pointer by Value”void func(TreeNode* root)Notice there is no &.
So the pointer itself is passed by value.
A copy of the pointer is created.
Memory before function call:
Caller
root -----> AAfter entering the function:
Caller Function
root -----> A root -----> A (copy)There are now two pointer variables.
Both point to the same node.
Reassigning the Pointer
Section titled “Reassigning the Pointer”root = root->left;Memory:
Caller Function
root -----> A root -----> BOnly the local pointer changes.
The caller’s root still points to A.
Modifying the Node
Section titled “Modifying the Node”root->val = 100;Memory:
Caller Function
root -----> Node <----- rootSince both pointers point to the same node,
root->val = 100;changes the actual node.
The caller also sees this change.
Why Doesn’t search() Change root?
Section titled “Why Doesn’t search() Change root?”TreeNode* search(TreeNode* root, int key) { while(root) {
if(root->val == key) return root;
else if(key < root->val) root = root->left;
else root = root->right; }
return nullptr;}Call:
TreeNode* node = search(root, key);Suppose:
10 / \ 5 20Initially:
deleteNode()
root -----> 10
search()
root -----> 10Inside the function:
root = root->right;Memory:
deleteNode()
root -----> 10
search()
root -----> 20Only the local copy moved.
The caller’s root still points to 10.
The function returns:
return root;So after:
TreeNode* node = search(root, key);Memory:
root -----> 10node -----> 20search() never changes the caller’s root because it received only a copy of the pointer.
Passing a Pointer by Reference
Section titled “Passing a Pointer by Reference”void func(TreeNode*& root)Notice the &.
Now the pointer itself is passed by reference.
No copy is created.
Memory:
Caller
root -----> A ^ |Function (reference)Both names refer to the same pointer variable.
Reassigning the Pointer
Section titled “Reassigning the Pointer”root = root->left;Memory:
Caller
root -----> BThe caller’s pointer is also changed.
Modifying the Node
Section titled “Modifying the Node”root->val = 100;The node also changes because the pointer still points to the same object.
Pass by Pointer vs Pass by Reference
Section titled “Pass by Pointer vs Pass by Reference”These are different concepts.
Pass an Object by Reference
Section titled “Pass an Object by Reference”void func(int& x)-
No copy of
int -
xis an alias for the caller’s variable
Pass a Pointer
Section titled “Pass a Pointer”void func(int* p)Call:
func(&a);Here:
-
A pointer variable
pis created. -
pis a copy of the address.
Memory:
Caller Function
a p -----> aChanging
p = nullptr;doesn’t affect the caller.
Changing
*p = 20;changes a.
Why the Confusion?
Section titled “Why the Confusion?”People often say:
“I’m passing a pointer.”
But that doesn’t tell how it is passed.
A pointer can be passed:
TreeNode* root→ Pointer passed by value
or
TreeNode*& root→ Pointer passed by reference
These are different.
Summary Table
Section titled “Summary Table”| Parameter | What is Passed? | Copy Created? | Can Change Caller’s Variable? | Can Modify Object? |
|---|---|---|---|---|
int x | Value | Yes | No | No |
int& x | Reference to int | No | Yes | Yes |
int* p | Copy of pointer | Yes | No (p = ...) | Yes (*p = ...) |
TreeNode* root | Copy of pointer | Yes | No (root = root->left) | Yes (root->val = ..., root->left = ...) |
TreeNode*& root | Reference to pointer | No | Yes (root = root->left) | Yes |
Key Rules to Remember
Section titled “Key Rules to Remember”-
Every parameter in C++ is passed by value by default.
-
Using
&changes it to pass by reference. -
A pointer is just another variable that stores an address.
-
TreeNode* rootmeans copy the pointer, not the tree. -
Two copied pointers can point to the same object, so modifying the object affects both.
-
root = root->leftchanges only the local copy when usingTreeNode*. -
TreeNode*& rootpasses the actual pointer variable, so reassigning it changes the caller’s pointer as well. -
Remember:
TreeNode*answers what the variable is (a pointer), while&answers how it is passed (by reference instead of by value).