Samar Yadav Samar Yadav - 1 month ago 4
C Question

Original value doesn't change while passing by reference?

I am practicing a linked-list code. Below is the insert function for that:

Node* insert_at_pos(Node *head, int pos){
struct Node *ptr=NULL;
printf("enter data\n");
ptr=(Node*) malloc(sizeof(Node));
scanf("%d",&ptr->data);
ptr->next=NULL;
if (pos==0){
if (head==NULL){
head=ptr;
return head; //return that I want to remove
}
}
printf("done\n");
}


Instead of returning
Node*
, if I return
void
, I think this code should still work because I am passing value by reference. So the value of
head
should update automatically instead of returning it, but it doesn't work if I remove the
Node*
and put
void
in the return type of
insert_at_pos
.

And, I am calling
insert_at_pos
function like this::

Node *head=insert_at_pos(head,0);


What could be the possible explanation or what is going wrong here?

Answer

There are basically two ways to handle this problem. Either you pass the address of the pointer (type Node**, pass &head) or you make a separate list type.

The second solution would look something like this:

typedef struct List {
    Node *head;
} List;

A new empty list can then be created like this:

List *list = malloc(sizeof (List));
list->head = NULL;

Both ways are fine. Conceptually, the second solution better matches the actual problem since it differentiates a List from the data Nodes. You can create a list and add or remove values without changing the list handle.

The first solution tries do skip a separate entity for the list by letting the list head be the list handle. The problem with that is that an empty list doesn't have any nodes, so an empty list is denoted by NULL. This means that the list handle changes when the list transitions from empty to non-empty or from non-empty to empty, so when you insert or remove items the list handle might change.

An insert function using the first solution could be declared like this:

void insert(Node **head, int value);

a call would look like this:

Node *head = null;
insert(&head, 42);

Or it could be declared like this (like in your question):

Node* insert(Node *head, int value);

and called like this:

Node *head = null;
head = insert(head, 42);
Comments