0

I've been at this for awhile; linked lists have always been a problem. By this I mean, I've already watched the shorts and done a ton of reading. A ton. Below is how I'm trying to think about reading in a new linked list from a dictionary file. Then I want to print it to see if the list was actually built.

1.I don't know how to read in the list properly.

2.I dont know how to get the list out of the while loop scope so I can read it into the for loop. See the **** row.

Without the for loop, it runs without errors, but I have no idea if it actually works.

// #include "../pset5/speller/dictionaries/small"

int main(void)
{
  typedef struct node
  {
    char *word;
    struct node* next;
  }
  node;

//declare mem pointer up here, to use below
      node *mem = NULL;
      // blank string store
      char line[100];
      // head of list
      node *head = NULL;

     //****try to make ptr to ptr to use in for loop to print out list at bottom
      node ** memPtr = mem;


  FILE *inptr = fopen("../pset5/speller/dictionaries/small", "r");

  // scan file from inptr to line
  while(fscanf(inptr,"%s",line) != EOF)
  {
    // malloc mem
    mem = malloc(sizeof(node));
      if(mem == NULL)
      {
        return 1;
      }
      // first node
      if(head == NULL)
      {
      // copy line into node's word
        mem->word = line;
        // make next null
        mem->next = NULL;
        // this node the head
        head = mem;

      } else {
        // if second node +

        // set to line
        mem->word = line;
        // set next to previous node's head
        mem->next = head;
        // set head to current new node
        head = mem;

      }

  }
 //try and set *ptr to a the malloc inside the while loop
   for (node *ptr = memPtr; ptr != NULL; ptr = ptr->next)
    {
        printf("%s\n", ptr->word);
    }
}

I also posted about this here also and have not had any great help yet https://www.reddit.com/r/cs50/comments/8d294t/help_making_linked_list_in_c/

1 Answer 1

1

Believe it or not, your problem isn't with linked lists, it's with pointers. Let's see if I can walk you through this.

First, every word (line) is being stored in the char array line[100] as its being processed. Now, look at the node structure. char * word; means that word is defined as a pointer to a char (or char string or char array).

Now, think about what happens as this code executes. mem->word = line; No matter what word is being processed, the starting address of the line[] array is stored here. When the entire dictionary file is processed, every node has node->word pointing at line. That means that every node will be pointing at the last word processed from the input file. If you were to change the contents of the line array, every node would point at that new word.

You have to remember what's happening. Are you trying to copy an address where a string is stored or the actual string? In this case, you'd need to store the string somewhere else. There are two main choices here.

  1. Malloc memory to the pointer in the node and copy the word into that memory, or
  2. Declare word in the struct as a char array of sufficient length and copy the word into the array.

This will make sure that each word has it's own place to live.

More importantly, = doesn't copy a string. It's great for copying the address of a string though. If you want to copy a string, then strcpy or one of its cousins will be your friend.

As for the rest of the code, there are minor issues. First, get rid of the dereferenced pointer node ** memPtr A single asterisk would suffice. Simpler further to print out the list, create a pointer to a node and set it equal to head and use it in your for loop and it'll be fine.

Finally, if you're hardcoding the dictionary file name, make sure the file is where the hardcode says or it'll generate a seg fault.

There may or may not be other issues, but you need a chance to work through them. ;-)

If this answers your question, please click on the check mark to accept. Let's keep up on forum maintenance. ;-)

5
  • Can I keep char line[100] as is though? 100 is arbitrary for a long string. I am trying to use your approach #2. I'll copy a string there with: strcpy(mem->word, line); mem->next = NULL; head = mem; (for first node) But then I get runtime error: null pointer passed as argument 1, which is declared to never be null. This is why I got rid of strcpy. I want to put line into mem->word. I want each node to get from line[100], taking it's value, and then having the loop overwrite the value inside for the next node.OR line does not work as is at all?
    – Mote Zart
    Commented Apr 22, 2018 at 13:43
  • If you want to copy the string into mem->word, then mem->word needs to have memory allocated to it or it needs to be a char array. Currently, it's a pointer with no memory allocated to it, so you get that error.
    – Cliff B
    Commented Apr 22, 2018 at 18:00
  • Isn't mem = malloc(sizeof(node)); allocating memory? I thought this was a pointer to some memory. Obviously it is not working, but that is why I put that there.
    – Mote Zart
    Commented Apr 22, 2018 at 23:22
  • It does allocate memory, but only for the node itself. The element inside the struct, node->next, is a pointer to more memory, but hasn't had any memory allocated to it. Remember how malloc works. It reserves memory to the program and returns the address of that memory, which you have to then store in a pointer. That's why I said you had to either malloc memory for the word or change the struct to have a char array (which would be allocated with the malloc) instead of a pointer for word.
    – Cliff B
    Commented Apr 22, 2018 at 23:31
  • To put it another way, the malloc allocates memory for the elements of the node itself, but not memory that those pointers might point at. (If it did, it could become a recursive process that would suck up all available memory. If it allocated the memory that the pointer would point at, then it would have to allocate memory that the next pointer in the chain would point at, and so on without end.)
    – Cliff B
    Commented Apr 22, 2018 at 23:38

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .