Zhou Yi
Zhou Yi

Reputation: 65

Confused with Pointer Reference and Pointer

I am trying to create one singly linked list and swap two int element in sub- function.

  1. in function swap(int *a,int *b) , the type of parameter is int *,and it can work successfully.
  2. in function build_sll(node *head), the singly linked list won't be created successfully.
  3. Once I set the type of parameter to be build_sll(node *&head),and it will be created singly linked list successfully.

Confused with:

function swap(int *a,int *b) passed the address of a b, I could modify the value of a b . function build_sll(node *head) passed only the value of pointer head. I could not modify the value of head. why here does not pass the address of head. The only difference between them is their data type.

while set build_sll(node *head), after GDB my code, and I found that all the node object have been created successfully. In main if I visited the allocated address, it does record the node information. how to delete memory in such case.

See my code to make clear my question.

#include<iostream>
#include<cstdlib>
#include<memory.h>

using namespace std;

typedef struct node{
    int num;
    struct node * next;

    node(int num,struct node * next)
    {
        this->num = num;
        this->next = next;
    }

}node;

void build_sll(node *&head);
void del_memory(node *&head);
void travel_sll(node *head);
void swap(int *,int *);

int main()
{
   int a =10 ,b = 5; 
   node *head = NULL;

    build_sll(head);
    travel_sll(head);
    del_memory(head);

    swap(&a,&b);
    cout << a <<"  "<< b <<"\n";

    exit(0);
}

void build_sll(node *&head)
{
    head = new node(0,NULL);
    node * tail = head;

    for(int index = 1 ; index < 8;index++)
    {
         node * temp = new node(index,NULL);
         tail -> next = temp;
         tail = temp;
    }
}

void travel_sll(node *head)
{
    if(head)
    {
        head = head -> next;
        while(head)
        {
            cout << head->num <<"\n";
            head = head -> next ;
        }
    }
}

void del_memory(node *&head)
{
    delete [] head;
}

void swap(int *a,int *b)
{
    int t;
    t = *a;
    *a = *b;
    *b = t;
}

Upvotes: 4

Views: 176

Answers (3)

davmac
davmac

Reputation: 20631

function swap(int *a,int *b) passed the address of a b, I could modify the value of a b . function build_sll(node *head) passed only the value of pointer head. I could not modify the value of head. why here does not pass the address of head. The only difference between them is their data type.

Well:

swap(&a,&b);

Here you're passing the address of a, and of b - that is, you're constructing pointers which point at the values that a and b refer to, and passing those pointers as arguments to the swap function.

build_sll(head);

Here you're passing the value of head (which happens to be a pointer variable). The value passed points at something (or is null), but it doesn't point at the value that head itself refers to..

If you look inside build_s11, assuming it was declared to receive a node * parameter:

void build_sll(node *head)
{
    head = new node(0,NULL);

Then you'll not that the parameter is also called head - but this is coincidental. What it does mean is that assignment is just changing the value of the parameter variable, not of the original variable. That is, head inside build_s11 is a different variable to head in the calling expression; there are two variables, and you are modifying the one inside the function, but not the one in the caller.

So why doesn't it behave the same way in swap? Well, the fundamental difference is that in build_s11 you are assigning to the parameter variable itself, whereas in swap you are assigning to the pointer target:

*a = *b;

If you wanted to see consistent behaviour, you should use consistent syntax. build_s11 could be declared as:

void build_sll(node **head);

and you would call it as:

build_sll(&head);

... and then you could change the value of of a passed-by-pointer node * value by assinging to *head:

void build_sll(node **head)
{
    *head = new node(0,NULL);
    node * tail = *head;

... etc. Note that it is now consistent: just as in swap you used *a and *b (rather than plain a and b), you are now using *head in build_s11 (rather than head).

Of course you can also use a reference, as you have done in your full code posting.

Upvotes: 1

buld0zzr
buld0zzr

Reputation: 962

If I understood the first question correctly, you're confused why you can modify the values of a and b through pointers, and can't modify the value of head through the same syntax.

If this is the case, this happens because the type of a and b is int, and int *a points to the address of the variable in memory, thus enabling you to modify in the function through dereference. You could implement the swap function like this:

void swap(int &a,int &b)
{
    int t;
    t = a;
    a = b;
    b = t;
}

and swap(a,b) would work.

As you correctly noticed, the datatype of head is different, it's node *. To modify it's value you need a pointer to the memory address, where pointer itself is stored. Thus, you need to pass a reference to the node *head to modify it. build_sll function could be implemented with dereferences too

void build_sll(node **head)
{
    *head = new node(0,NULL);
    node * tail = head;

    for(int index = 1 ; index < 8;index++)
    {
         node * temp = new node(index,NULL);
         tail -> next = temp;
         tail = temp;
    }
}

However, the syntax with double pointers is not preferred, as it leads to using dereferences constantly, so it's better to use a & syntax

Upvotes: 1

Mohit Jain
Mohit Jain

Reputation: 30489

function swap(int *a,int *b) passed the address of a b, I could modify the value of a b . function build_sll(node *head) passed only the value of pointer head. I could not modify the value of head. why here does not pass the address of head. The only difference between them is their data type.

In function swap, you want to modify/access the value of int so passing int * or int & would work. Passing arguments of type int is good for reading the value of arguments, but if you change it, only local copy is updated and not the values with which you called the function.

In function build_sll you want to change the argument of type node *. So you should pass argument of type node ** or node *& to ensure you can change the value with with it was called. Passing node * would only change the local copy (in called function) and original value in the callee function would remain unchanged.

Your options are:

  • Preferable node * build_sll(node *);
  • OK node * build_sll(node *&);
  • Avoid this: node * build_sll(node **); etc

Upvotes: 1

Related Questions