0

Passing a pointer is basically like passing a pointer as value.. the changes to the pointer internally in the function will not modify the actual value of the pointer.. but when we need to access on the actual pointer itself in a function, then we are coming up with the pointer to pointer concept. this is my understanding..

            struct node
            {
                int data;
                struct node* next;
            };

            void push(struct node** head_ref, int new_data) // i understand the need of pointer to pointer here, since we are changing the actual value by adding a node..
            {
                struct node* new_node = (struct node*) malloc(sizeof(struct node));
                new_node->data  = new_data;
                new_node->next = (*head_ref);
                (*head_ref)    = new_node;
            }

            void insertAfter(struct node* prev_node, int new_data) // why are we not using pointer to pointer here since even here the pointer data is getting modified..??
            {
                if (prev_node == NULL)
                {

                  return;
                }

                struct node* new_node =(struct node*) malloc(sizeof(struct node));
                new_node->data  = new_data;
                new_node->next = prev_node->next;
                prev_node->next = new_node;
            }

            int main()
            {
                struct node* head = NULL;

                append(&head, 6);
                insertAfter(head->next, 8);

                return 0;
             }

Please clarify.. i'm confused why we are not using pointer to pointer in InsertAfter(...) as well thought we change the pointer there?

CuriousToLearn
  • 153
  • 1
  • 12
  • In C++, you don't repeat `struct` each time you refer to the `struct`. Also, in general don't use `malloc`. This is important once you add constructors to your `struct` or `class` types. – crashmstr Oct 31 '14 at 19:14
  • _"but when we need to access on the actual pointer itself in a function, then we are coming up with the pointer to pointer concept. this is my understanding.."_ That's basically correct, you'll need pointer to pointer, or reference to pointer, if you want to change the pointer value from within a function. Though it looks more that you suspect or have some problems with your code. Did you have any particular questions about it? – πάντα ῥεῖ Oct 31 '14 at 19:16
  • yeah.. i had put my doubt in the code as a comment in the code itself..i wanted to know why insertAfter(...) did not have pointer ?to pointer though it is changes the value of the pointer... why are they maintaining single pointer concept itself.. – CuriousToLearn Oct 31 '14 at 19:23

3 Answers3

0

You are correct in the beginning, but typically if you want to alter the original value, then you pass the pointer by reference(&) instead of by value(*)

Here is something to read: http://courses.washington.edu/css342/zander/css332/passby.html

0

In the second function you are not modifying the prev_node position or address ,you are only changing the data.So you only need to pass by value.

Chinmay Hegde
  • 117
  • 3
  • 10
  • ok. let say we have a delete function that deletes a node at the end. then in this case, we are not changing the node's address. so pass by value is enough? void DeleteAtEnd(struct node* node); – CuriousToLearn Oct 31 '14 at 19:35
0

The difference is what the functions do with what you pass in.

This modifies what *head_ref itself points to:

void push(node** head_ref, int new_data);

While this modifies the contents of the node that prev_node points to - but it still will end up pointing to the same node:

void insertAfter(node* prev_node, int new_data);

Looking at actual usage clears this up too:

// head points to the node 0
node* head = new head{0, nullptr}; 

// head now points to the node 5, which itself points to the node 0
// so our list is {5} --> {0}
push(&head, 5); 
     ^
     additional clue that we are modifying head

// head->next points to the node 0 before this
// it **still** continues to point to that node after the call, but we 
// change what comes after it, to now be a new node 3
// so our list is {5} --> {0} --> {3}
insertAfter(head->next, 3);

// head is still the 5. head->next is still the 0. 
Barry
  • 286,269
  • 29
  • 621
  • 977
  • ok. let say we have a delete function that deletes a node at the end. then in this case, we are not changing the node's address. so pass by value is enough? void DeleteAtEnd(struct node* node); – CuriousToLearn Oct 31 '14 at 19:37
  • Yes. Although You'll have to make sure that the node in front of the node you're deleting will get updated to point to the node after the node you're deleting. – Barry Oct 31 '14 at 19:38
  • are you talking about deleting a node @ front? if we are deleting @ front, there is a change in the pointer's address right? then it should be a pointer to pointer and if we want to delete a node @ end, then its a single pointer. is my understanding is correct? – CuriousToLearn Oct 31 '14 at 19:47
  • There is no change of address. I'm saying if you delete node `B` when the list is `A --> B --> C`, you have to make sure that you end up with the list `A --> C` and not `A --> {deleted pointer}`. Which is not possible with a singly linked list if your function signature is just `void DeleteNode(node* );` – Barry Oct 31 '14 at 19:50