'C - Linked list printing extra link

My program is printing one more link, at the beginning, than what I'm supposed to have. I can't find the problem in my debugging.

Also, I'm unsure if my sorting is optimal.

I've added the text I'm testing with, I should have in total 26 links but I'm getting 27.

NEWLY CHAINER READ ELEMENTS KAFKA YOUNG IS WELL SKILLED ZAPPED AT
PUBLISHED METAMORPHOSIS IMAGINE HIS A FRANCHISE WHEN WORLDWAR RAGEID VANQUISHED
TUBERCULOSIS XENOPHOBIA YET GREATLY ULTIMATELY 

I know the problem is happening at init_and_sort_link().

#include "stdio.h"
#include <stdlib.h>
#include <string.h>
const int FILEWORDNUMBER = 46;

struct link {
    char *word;
    struct link *next;
};

void init_and_sort_link(char **words, struct link *head) {
   for (int i = 0; i < FILEWORDNUMBER; ++i) {
      if (words[i] != 0) {
         struct link *temp;
         temp = head;
         temp = malloc(sizeof(struct link));
         temp->word = words[i];
         temp->next = NULL;

         if (strcmp(head->word, temp->word) < 0) {
            temp->next = head;
         } else {
            struct link *cur = head;
            while (cur->next != NULL &&
                   strcmp(temp->word, cur->next->word) >= 0) {
               cur = cur->next;
            }
            temp->next = cur->next;
            cur->next = temp;
         }
      }
   }
}

void readLine(FILE *file, char **words) {
   int i = 0;
   char ligne[80];
   while (fgets(ligne, 80, file)) {
      char *word = strtok(ligne, " ,.-\n");
      while (word != NULL) {
         words[(i)++] = strdup(word);
         word = strtok(NULL, " ,.-\n");
      }
   }
   fclose(file);
}

int main(int argc, char *argv[]) {
   FILE *file = fopen(argv[1], "r");
   char **words = calloc(FILEWORDNUMBER, 30 * sizeof(char *) + 1);
   readLine(file, words);
   struct link *head = malloc(sizeof(struct link));
   struct link *ptrr = head;
   //head->word = words[0];
   head->next = NULL;
   init_and_sort_link(words, head);
   int a = 0;
   while (ptrr != NULL) {
      printf("Link#%d ->%s\n", a, ptrr->word);
      ptrr = ptrr->next;
      a++;
   }
   struct link *tmpp;
   while (head != NULL) {
      tmpp = head;
      head = head->next;
      free(tmpp);
   }
   for (int i = 0; i < FILEWORDNUMBER; ++i) {
      free(words[i]);
   }
   free(words);
   return 0;
}


Solution 1:[1]

OK, there are a couple of things wrong here

First

Words is an array of pointers to strings, so it must be allocated like this

 char **words = calloc(FILEWORDNUMBER, sizeof(char *));

The 30*sizeof(char*) + 1) seems to be an effort to reserve space for strings. Not needed yet.

Second in init_and_sort_link we have

     struct link *temp;
     temp = head;  <<<<=== this line is meaningless as its overwritten by the next line
     temp = malloc(sizeof(struct link));
     temp->word = words[i];
     temp->next = NULL;

     if (strcmp(head->word, temp->word) < 0) {

The strcmp fails becuase head->word has not been set to anything. I am not sure what you want here tho

I can see that you commented out a line that would have inialized head->word in main. I see your problem now that I put that line back

I would change the structure of you program so that you do not create the head before calling the int_sort. Instead create all the links in that function and have it return the head to main.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1