PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Wednesday, July 6, 2022

[FIXED] How does reference to pointer exactly work in C++, and when do we need them (in the case of linked list)

 July 06, 2022     c++, pass-by-reference, pointers, singly-linked-list     No comments   

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 -

Function that works the same with Node* and Node* &


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 to head->next.
  • the function also returns this "new" head (pointing to head->next) and that is assigned to head.

So you basically asign to headtwice. 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)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing