Search code examples
cstructlinked-listdynamic-memory-allocationsingly-linked-list

How to store the data dynamically in linked list in C?


I'm trying to store the values in the linked list dynamically.

I want the user to input the size of the linked List. Then based on the input I want to allocate the memory (i.e if Input : 3 then three nodes should be created).

If memory is allocated for nodes then I store the head node in a temp.

After that I want to store the data in list untill list comes to the end

The algorithm which I used is following

#include <stdio.h>
#include <stdlib.h>

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


// Printing the list
void printList(struct node *ptr)
{
    int i = 1;
    while(ptr != NULL)
    {
        printf("\n Value in Node %d : %d",i ,ptr->data);
        ptr = ptr->next;
        i++;
    }
}

int main()
{
    int n;
    struct node *head;
    struct node *temp;
    printf("\n Enter the size of linkedList : ");
    scanf("%d",&n);
    head = malloc(sizeof(struct node) * n);

    // Storing head in temp
    temp = head;
    int i = 1; // Keep track on the position of the list
    while(temp != NULL) // Untill temp get to end of the list
    {
        printf("\n Enter the value in node %d : ", i);
        scanf("%d",&temp->data);
        temp = temp->next; // Assinging next list address
    }
    printList(head);
    return 0;
}

I don't understand why it printing only one value when I'm executing it.

I don't know how wrong I was?

**OUTPUT : **

$ clang dynamicList.c -o a

$ ./a

Enter the size of linkedList : 10

Enter the value in node 1 : 9

Value in Node 1 : 9


Solution

  • This call of malloc

    head = malloc(sizeof(struct node) * n);
    

    allocates an uninitialized memory.

    Thus this statement in the while loop

    temp = temp->next;
    

    assigns an indeterminate value to the pointer temp and using this pointer further in the loop invokes undefined behavior.

    Moreover the condition in the loop

    while(temp != NULL) // Untill temp get to end of the list
    

    does not make a sense.

    This declaration within the block scope of the loop

    int i = 1; // Keep track on the position of the list
    

    and the similar declaration in the function printList

    int i = 1;
    

    also do not make a sense.

    You need to initialize exactly n nodes. So the loop should look like

    for ( int i = 0; i < n; i++ )
    {
        //...
    }
    

    Also you should free all the allocated memory when the list will not be needed any more.

    Pay attention to that you allocated an array of nodes. Using your approach the program can look the following way.

    #include <stdio.h>
    #include <stdlib.h>
    
    struct node 
    {
        int data;
        struct node *next;
    };
    
    // Printing the list
    void printList( const struct node *ptr ) 
    {
        for ( unsigned int i = 1; ptr != NULL; ptr = ptr->next )
        {
            printf( "Value in Node %u : %d\n", i++, ptr->data );
        }
    }
    
    int main( void ) 
    {
        unsigned int n = 0;
        struct node *head = NULL;
    
        printf( "Enter the size of linkedList : " );
        scanf( "%u", &n );
    
        head = malloc( n * sizeof( struct node ) );
        
        struct node *temp = head;
        for ( unsigned int i = 0; i < n; i++ )
        {
            printf( "Enter the value in node %u : ", i + 1 );
            scanf( "%d", &temp->data );
            temp->next = i == n - 1 ? NULL : temp + 1;
            ++temp;
        }
        
        printList( head );
        
        free( head );
        
        return 0;
    }
    

    The program output might look like

    Enter the size of linkedList : 10
    Enter the value in node 1 : 1
    Enter the value in node 2 : 2
    Enter the value in node 3 : 3
    Enter the value in node 4 : 4
    Enter the value in node 5 : 5
    Enter the value in node 6 : 6
    Enter the value in node 7 : 7
    Enter the value in node 8 : 8
    Enter the value in node 9 : 9
    Enter the value in node 10 : 10
    Value in Node 1 : 1
    Value in Node 2 : 2
    Value in Node 3 : 3
    Value in Node 4 : 4
    Value in Node 5 : 5
    Value in Node 6 : 6
    Value in Node 7 : 7
    Value in Node 8 : 8
    Value in Node 9 : 9
    Value in Node 10 : 10
    

    If you indeed want to organize data as a list instead of an array then the program can look the following way

    #include <stdio.h>
    #include <stdlib.h>
    
    struct node 
    {
        int data;
        struct node *next;
    };
    
    // Printing the list
    void printList( const struct node *ptr ) 
    {
        for ( unsigned int i = 1; ptr != NULL; ptr = ptr->next )
        {
            printf( "Value in Node %u : %d\n", i++, ptr->data );
        }
    }
    
    int main( void ) 
    {
        unsigned int n = 0;
        struct node *head = NULL;
    
        printf( "Enter the size of linkedList : " );
        scanf( "%u", &n );
    
        struct node *temp;
        for ( unsigned int i = 0; i < n; i++ )
        {
            if ( i == 0 )
            {
                head = malloc( sizeof( struct node ) );
                temp = head;
            }
            else
            {
                temp->next = malloc( sizeof( struct node ) );
                temp = temp->next;
            }
            printf( "Enter the value in node %u : ", i + 1 );
            scanf( "%d", &temp->data );
            
            temp->next = NULL;
        }
        
        printList( head );
        
        while ( head != NULL )
        {
            temp = head;
            head = head->next;
            free( temp );
        }       
        
        return 0;
    }
    

    The program output might look as shown for the previous demonstrative program.