yimin ZHOU
yimin ZHOU

Reputation: 5

How to change the data of a node in Linked list in C?

struct:

//linked list
struct list
{
  int32_t data;
  struct list *next;
};

struct list *head;

at first, initialize linked list (every node be 0):

void initLinkedList(int size)
{   
    head = (struct list*)malloc(sizeof(struct list)*size);
    struct list *current = head;

    for(int i = 0; i < size; i++)
    {
        (current+i)->data= 0;
    }
}

function:

void changeNode(int32_t element, int index)
{   
    struct list *current = head;

    for (int i = 0; i < index; i++)
    {
        current = current->next;
        
    } 

    current->data= element;
}

so basically, I want to create a linked list with size nodes, then change the data of the node through function.

But I'm getting Segmentation fault at this line in function: current->localVar = element;

So, how can I change the data of a node without inserting a new one?

Upvotes: 0

Views: 1700

Answers (2)

Shubham
Shubham

Reputation: 1153

So, here void initLinkedList(int size) you aren't creating/initializing a linked list instead you are declaring an array of type struct list dynamically with size no. of elements and then you are initializing all of them with value 0.

To initialize your linked list code this:

void initLinkedList(int size)
{
    if((head = (struct list*)malloc(sizeof(struct list)*size)) == NULL)
    {
        printf("Memory Unavailable.\n");
        exit(1);
    }
    struct list *current = head;

    for(int i = 0; i < size; i++)
    {
        current->data = 0;
        if ((current->next = (struct list*)malloc(sizeof(struct list))) == NULL)
        {
            printf("Memory Unavailable.\n");
            exit(2);
        }
        current = current->next;
    }
    current->next = NULL;
}

Then to changeNode, code this:

void changeNode(int element, int index)
{
    struct list *current = head;
    int count = 0;
    while(count != index)
    {
        if(current->next)
            current = current->next;
        count++;
    }
    current->data = element;
}

Here I'm adding another function to print the linked list:

void print(struct list *head)
{
    if(head->next)
    {
        printf("%d", head->data);
        head = head->next;
        print(head);
    }
}

main():

int main(void)
{
    initLinkedList(5);
    changeNode(5, 4);
    print(head);
    delete(head);
    printf("Memory freed.\n");
    return 0;
}

Now you can see the Sample Output:

00005
Memory freed.

One more thing, if you are confused about this:

if ((current->next = (struct list*)malloc(sizeof(struct list))) == NULL)

I can help you. In the above line of code, we're allocating memory to current->next and checking if memory is allocated successfully or not.

Freeing the memory allocated to linked list using delete() function:

void delete( struct list *head )
{
  struct list *current = head;
  struct list *next = NULL;
  while(current != NULL)
  {
    next = current->next;
    free(current);
    current = next;
  }
}

Upvotes: 0

David C. Rankin
David C. Rankin

Reputation: 84561

You must consider whether you have requested to change an index that doesn't exist in your list, but otherwise you are close. You are not iterating your initLinkedList in a traditional manner (you are treating the list like an array) As a side-note: In C, there is no need to cast the return of malloc, it is unnecessary. See: Do I cast the result of malloc?.

Let's start with your initLinkedList function. You have declared head globally (assuming) and then go to fill your list with zeros. In doing so, you never initialize any of your ->next pointers. You don't end up with a linked-list -- you have a block of allocated nodes.

You should iterate current = current->next; and set each ->next pointer, not just use the offset +i. You are able to initialize your data like that due to allocating all nodes in a continual block -- but any node added later will not be contiguous in memory and none of your ->next pointers are initialized.

Now on to your changeNode function. You must fix your initLinkedList to initialize the ->next pointers. Then you need to change the return type from void to struct list* so you can return a pointer to the changed node on success or NULL on failure. Currently, you have no way of knowing if your change succeeded or failed.

Making the changes you could do:

struct list *changeNode (int32_t element, int index)
{
    struct list *current = head;

    for (int i = 0; i < index; i++) {
        if (!current->next) {
            fputs ("error: request exceeds no. of nodes in list.\n", stderr);
            return NULL;
        }
        current = current->next;
    }
    current->data = element;

    return current;
}

Look things over and let me know if you have further questions.

Upvotes: 2

Related Questions