Issue
I know that pointers hold the address of a variable. And references point to the same address in the symbol table (that is, the same address of the variable, that they are assigned to).
My question is, how do reference to pointers exactly work. And when do we need them, as opposed to using pointer alone (and not using reference to pointer). It will be helpful if you could explain me the use of reference to pointer, with respect to a singly linked list.
I have the following code that deletes the head pointer of a linked list using a function:
struct Node
{
int data;
Node* next;
};
struct Node* newNode(int data)
{
Node* temp = new Node;
temp->data = data;
temp->next = nullptr;
return temp;
}
Node* deleteHead(Node* &head)
{
if (head)
{
Node* temp = head;
head = head->next;
delete temp;
}
return head;
}
int main()
{
Node* head = newNode(1);
head->next = newNode(6);
head->next->next = newNode(4);
head->next->next->next = newNode(8);
head = deleteHead(head);
Node* temp = head;
while (temp != nullptr)
{
cout << temp->data << " " << endl;
temp = temp->next;
}
return 0;
}
In the deleteHead(Node* &head)
function, the function takes the argument, Node* &head
. But, the code works fine, even when the argument is Node* head
. for what cases do we need to pass Node* &
instead of Node*
in a linked list?
Following is the deleteHead(Node* &head)
function above, which works the same, if we only use Node* head
as the argument, instead of Node* &head
-
Solution
You pass a pointer by reference for the same reason you pass a non-pointer by reference: To let the function modify its value.
Let me use a simpler example
#include <iostream>
void foo(int*& x) {
*x = 42; // change the value of the int x points to
x = nullptr; // change the value of x
}
The first line modifies the value x
points to (but it does not modify x
). The second line modifies x
itself.
int main() {
int y = 42;
int* y_ptr = &y;
foo(y_ptr);
if (y_ptr == &y) std::cout << "cannot happen";
}
Because we set x = nullptr
, y_ptr
will not point to y
anymore after the call.
Now if we modify foo
to not take a reference we get:
#include <iostream>
void foo(int* x) {
*x = 42; // change the value of the int x points to
x = nullptr; // change the value of x
}
Again the first line modifies the int
pointed to by x
. However, now the second line only has an effect on x
local to the function.
int main() {
int y = 42;
int* y_ptr = &y;
foo(y_ptr);
if (y_ptr == nullptr) std::cout << "cannot happen";
}
The value of y_ptr
cannot change by passing it to foo
, because it is passed by value.
In your code you have
Node* deleteHead(Node* &head)
{
if (head)
{
Node* temp = head;
head = head->next;
delete temp;
}
return head;
}
And when you write head = deleteNode(head)
two things are happening:
- the function modifies
head
(because it is passed by reference) to point tohead->next
. - the function also returns this "new" head (pointing to
head->next
) and that is assigned tohead
.
So you basically asign to head
twice. Because head
is passed by reference deleteNode
would do the right thing without using the return value:
deleteNode(head); // this already does modify head
...or put the other way around: If you return the "new" head (head->next
) from the fucntion and assign it to head
, then it does not matter if you pass the pointer by reference, because the assignment done inside the function has the same effect.
Your code is similar to
int* bar(int*& x) {
x = nullptr;
return x;
}
and then call it via
int y = 42;
int* y_ptr = &y;
y_ptr = bar(y_ptr);
where the same effect could be achieved by not using the returned value bar(y_ptr)
. Or the same without pointers (because pointers really make no difference here):
int moo(int& x) {
x = 0;
return x;
}
int x = 42;
x = moo(x); // same as `moo(x)`
PS: You dont need both (return the pointer and assign it already in the function), so better make the function return void
.
Answered By - 463035818_is_not_a_number Answer Checked By - Dawn Plyler (PHPFixing Volunteer)
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.