Search code examples
cpointerslinked-listinfinite-looptail

Inserting at the end of a linked list using a tail pointer, then printing the list cause infinite loop


I'm creating a program that: 1)reads some words terminated by "STOP" 2)inserts each of them at the end of a linked list using a tail pointer 3)then prints every word

When I try to print the list, the output is an infinite loop of the the first inserted word.

 //max len of a word in input
#define WORD 20 

//define a node for a linked list
typedef struct node_l{
    char string[WORD+1];
    struct node_l *next;
}Node_L;

Node_L *newNode_L(char *word);
char *readword(void);
void printList(Node_L *list);
void insertNode_L(Node_L **list, Node_L **tail, char *word);
int main(){
    Node_L *root = NULL;
    Node_L *tail = NULL;
    char *word = readword();
    while(strcmp(word,"STOP")!=0){
        insertNode_L(&root,&tail, word);
        word = readword();
    }
    printList(root);
    return 0;
}

/*given head and tail pointer and a word:
    -creates a node containing the word
    -insert at the end of the linked list
*/
void insertNode_L(Node_L **list, Node_L **tail, char *word){
    Node_L *temp = newNode_L(word);
    if(*list==NULL){
        *tail = *list = temp;
    }else{
        Node_L *t = *tail;
        t->next = *tail;
        *tail = temp;
    }
}

//given a word returns a new node(linked list type) containing that word
Node_L *newNode_L(char *word){
    Node_L *node = malloc(sizeof(Node_L));
    if(node==NULL){
        printf("malloc failure\n");
        exit(EXIT_FAILURE);
    }
    strcpy(node->string, word);
    node->next = NULL;
    return node;
}

/*function that: 
    -first skips non alphabetical characters
    -reads every char until a not alphabetical character is inserted
    -returns a pointer to the first char of the new created string
*/
char *readword(void){
    int startWlen = 2;
    char *word= malloc(startWlen);
    //skips whitespace and char that are not alphabetical
    int c = getchar();
    while(!isalpha(c)){
        c = getchar();
    }
    int i=0;
    while(isalpha(c)){
        //realloc if necessary
        if(i==startWlen){
            startWlen*=2;
            char *temp = realloc(word, startWlen);
            if(temp==NULL){
                printf("realloc failure\n");
                exit(EXIT_FAILURE);
            }
            word = temp;
        }
        word[i]=c;
        i++;
        c = getchar();
    }
    //realloc if necessary for '\0' char
    if(i==startWlen){
        startWlen+=1;
        char *p =realloc(word,startWlen+1);
        if (p == NULL){
            printf("realloc failure\n");
            exit(EXIT_FAILURE);
        }else{
            word = p;
        }
    }
    word[i]='\0';
    return word;

}

//TRAVERSING A LINKED LIST
void printList(Node_L *list){
    int i=0;
    Node_L *p = list;
    while(p!=NULL){
        printf("%s is in pos %d \n", p->string,i);
        p = p->next;
        i++;
        if(i ==10) break; //to limit infinite loop
    }
}

Example:

 INPUT:train rocket ball STOP
    OUTPUT:
    train 
    train 
    train 
    train 
    train 
    train 
    train 
    train 
    train 
    train

Thanks in advance

NOTE like esplained in answers the problem was the insert function; Now I post here a corrected version of it:

void insertNode_L(Node_L **list, Node_L **tail, char *word){
    Node_L *temp = newNode_L(word);
    if(*list==NULL){
        *tail = *list = temp;
    }else{
        (*tail)->next = temp;
        *tail = temp;
    }
}

Solution

  • Problem is in the else block of your insertNode_L(...) method. It should be

    (*tail)->next = temp;
    *tail = temp;
    

    In your code

    Node_L *t = *tail;
    t->next = *tail;    // This makes tail point to itself resulting in an infinite loop
    *tail = temp;