Search code examples
cpointerslinked-listfree

Why does using free() lead to infinite looping


When I run the following code, it gives me an infinite looping result. However if I comment out the free pointer lines in the insert function i.e. free(ptr) and free(ptrnext) then it works fine. Can anybody explain why is it so?

I am pretty sure that the print and takeInput works fine, and hence can be ignored.

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

typedef struct Nodes{
    struct Nodes * next;
    int val;
}Node; 

//Function to create a linked list
Node * takeInput(){
    int data;
    Node *start =NULL ;
    Node *tail=NULL;

    printf("Enter the number of nodes"); 
    int num,i;
    scanf("%d",&num);
    for(i=1;i<=num;i++){
        if(start==NULL){
            start=malloc(sizeof(Node));
            puts("Enter data");
            scanf("%d",&data);
            start->val=data;
            start->next=NULL;
            tail=start;
        }
        else{
            Node * ptr = malloc(sizeof(Node));
            puts("Enter data" );
            scanf("%d",&data);
            ptr->val=data;
            tail->next=ptr;
            tail=tail->next;
        }   

    }   
    tail->next=NULL;        
    return start;
}

//Function to print
void print(Node * head){
    Node*ptr=head;
    while(ptr!=NULL){
        printf("%d->",ptr->val);
        ptr=ptr->next;
    }
}

//Function to insert a node in given linked list 
Node * insert(Node *start){
    int i,data;

    puts("Enter pos");
    scanf("%d",&i);

    puts("Enter data");
    scanf("%d",&data);

    Node * ptr=malloc(sizeof(Node));    
    ptr->val=data;
    ptr->next=NULL;

    if(i==1){

        ptr->next=start;
        start=ptr;

        free(ptr);  

    }
    else{
        Node * ptrnext=start;
        while(i!=1){
            ptrnext=ptrnext->next;
            i--;
        }

        ptr->next=ptrnext->next;
        ptrnext->next=ptr;

        free(ptr);
        free(ptrnext);

    }
    return start;
}

int main(void){
    Node * start =takeInput();  
    start=insert(start);
    print(start);
}

Solution

  • When I run the following code, it gives me an infinite looping result. However if I comment out the free pointer lines in the insert function i.e. free(ptr) and free(ptrnext) then it works fine.

    • This is undefined behavior. (when you don't comment the free() functions)

    • Once you've freed memory you must remember not to use it any more.

    Note : the pointer might or might not point the same block after freeing, it's undefined behavior

    • so don't free the pointer unless you want to destroy or delete the node.

    • so don't use the free() in the insert function as you are not deleting any node.


    • Apart from that, I don't see any function to deallocate the memory at the end of the program.

    • Always make sure to deallocate the allocated memory at the end using a delete() function.

    • Here's a typical implementation of delete function

      void delete(Node* start)
      {
           Node* temporary = NULL;
           while(start != NULL)
           {
               temporary = start->next; //saving next node address
               free(start); //freeing current node
               start = temporary; //assigning start with next node address
           }
      
           printf("successfully destroyed the list!"); //function exit message
      }
      
    • Call it at the end of main() function or when you wish to delete the entire list