Skip to content

Passing Pointers by Reference

Understand Mainly - Passing Pointers

A pointer is a variable that stores the address of another variable/object.

TreeNode* root;

Here:

  • root → Pointer variable

  • *root → The TreeNode object

  • root->val is equivalent to (*root).val

Example:

TreeNode node;
TreeNode* root = &node;

Memory:

node
+-------+
| val=5 |
+-------+
^
|
root (stores address of node)

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.


void func(int& x) {
x = 10;
}

Memory:

a = 5
x ----> a

No copy is created.

x is another name (alias) for a.

Changing x changes a.


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


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 -----> A

After entering the function:

Caller Function
root -----> A root -----> A
(copy)

There are now two pointer variables.

Both point to the same node.


root = root->left;

Memory:

Caller Function
root -----> A root -----> B

Only the local pointer changes.

The caller’s root still points to A.


root->val = 100;

Memory:

Caller Function
root -----> Node <----- root

Since both pointers point to the same node,

root->val = 100;

changes the actual node.

The caller also sees this change.


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 20

Initially:

deleteNode()
root -----> 10
search()
root -----> 10

Inside the function:

root = root->right;

Memory:

deleteNode()
root -----> 10
search()
root -----> 20

Only 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 -----> 10
node -----> 20

search() never changes the caller’s root because it received only a copy of the pointer.


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.


root = root->left;

Memory:

Caller
root -----> B

The caller’s pointer is also changed.


root->val = 100;

The node also changes because the pointer still points to the same object.


These are different concepts.

void func(int& x)
  • No copy of int

  • x is an alias for the caller’s variable


void func(int* p)

Call:

func(&a);

Here:

  • A pointer variable p is created.

  • p is a copy of the address.

Memory:

Caller Function
a p -----> a

Changing

p = nullptr;

doesn’t affect the caller.

Changing

*p = 20;

changes a.


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.


ParameterWhat is Passed?Copy Created?Can Change Caller’s Variable?Can Modify Object?
int xValueYesNoNo
int& xReference to intNoYesYes
int* pCopy of pointerYesNo (p = ...)Yes (*p = ...)
TreeNode* rootCopy of pointerYesNo (root = root->left)Yes (root->val = ..., root->left = ...)
TreeNode*& rootReference to pointerNoYes (root = root->left)Yes

  1. Every parameter in C++ is passed by value by default.

  2. Using & changes it to pass by reference.

  3. A pointer is just another variable that stores an address.

  4. TreeNode* root means copy the pointer, not the tree.

  5. Two copied pointers can point to the same object, so modifying the object affects both.

  6. root = root->left changes only the local copy when using TreeNode*.

  7. TreeNode*& root passes the actual pointer variable, so reassigning it changes the caller’s pointer as well.

  8. Remember: TreeNode* answers what the variable is (a pointer), while & answers how it is passed (by reference instead of by value).