Thread: linked list newbie

  1. #1
    Registered User
    Join Date
    Sep 2009
    Posts
    61

    linked list newbie

    Hi all!

    I'm new to linked lists. I hope the beginning of the code is OK. In any case the end of the code is wrong according to the compiler.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    char string[10];
    struct node
    {
    	char *word;
    	struct node *next;
    };
    
    int main(void)
    {
    
    	struct node *Head=NULL;		
    	Head = malloc( sizeof(struct node));  
    	struct node *root=NULL;
    	Head->next = root;
    
    	while(string[0] !='q')
    	{
    		printf("\nInput string:\n");
    		scanf("%s", string);
    		root = malloc( sizeof(struct node));  
    		root->word = string;
    		root->next = root;
    	}
    	printf("\nHere is the list:\n");
    	struct node* current = Head;
    	while (current != NULL)
    	{ 
    		printf(" %s\n"),word;
    		current = current->next;
    	}
    	struct node* current = Head;
    	while (current != NULL)
    	{ 
    		free(node*);
    		current = current->next;
    	}
    
    	return 0;
    }
    Thanks in advance for help.

  2. #2
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Well you have two obvious syntax related errors, do you know how to fix those?

    Also, (correctly) copy into word what you want it to contain, don't just assign the pointer. What will happen is string will change with each iteration of the while loop, but since all the words just point to string, it will look like all entries have the same word.

    > root->next = root;

    If root is going to be the pointer that walks the list then you should be doing something like

    root = root->next = NULL;
    Last edited by whiteflags; 12-05-2009 at 10:09 AM.

  3. #3
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by whiteflags View Post
    If root is going to be the pointer that walks the list then you should be doing something like

    root = root->next = NULL;
    Why would you attempt to access a member of something which you are saying is going to be NULL? That's bad.


    Quzah.
    Hope is the first step on the road to disappointment.

  4. #4
    Registered User
    Join Date
    Sep 2009
    Posts
    61
    Thanks for the answers!

    Unfortunately I don't know how to fix the problem with printing the strings and how to free memory. I just copied the "current" loop idea from Linked List Basics

  5. #5
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Well those are pretty fundamental things you don't know how to do. If you keep reading that resource and practice along side it you will get what to do in the general case for linked lists.

    Anyway, as long as you store a copy of the word and use printf you can print the strings, so there is one problem solved. Like I said earlier, assigning pointers will not do what you want. You want to call strcpy(word , string); after you've allocated space for the word entry.

    If you're going to insert a lot of consecutive values I typically implement it with at least two types of pointers. I use a pointer to know where I am in the list, and to connect the list together, and another for the allocation. Other than that I think you have the idea down. Just do what I'm neglecting to do right now: debug your code.

    When you delete the linked list, make sure you remember your place in the list until you're finished.
    Code:
    struct node *p = head;
    struct node *n = NULL;
    while ( p ) {
       n = p->next;
       free(p->word);
       free(p);
       p = n;
    }

  6. #6
    Registered User
    Join Date
    Sep 2009
    Posts
    61
    Thanks a lot!

    I fixed it

  7. #7
    Registered User
    Join Date
    Sep 2009
    Posts
    61
    hmmm... I thought I had fixed it... but now I get:
    glibc detected *** test5: double free or corruption
    ...after the scanf-loop.

    any ideas?


    here is the code
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    char string[10];
    struct node
    {
    	char *word;
    	struct node *next;
    };
    
    int main(void)
    {
    
    	struct node* head = NULL;
    	struct node* p = NULL;
    	struct node* n = NULL;
    	
    	
    	head = malloc(sizeof(struct node));
    	head->word = malloc(10);
    	head->word = "List:";
    	n = head->next;
    	
    	while ( string[0] !='q' ) 
    	{
    		p = n;
    		printf("\nInput string:\n");
    		scanf("%s", string);
    		p = malloc(sizeof(struct node));
    		p->word = malloc(10);
    		strcpy(p->word, string);
    		n = p->next;
    	}
    	
    	printf("\n%s",head->word);
    	p = head->next;
    	while(p!=NULL)
    	{
    		printf("\n%s",p->word);
    		p = p->next;
    	}
    
    	n = head->next;
    	free(head->word);
    	free(head);
    	p = n;
    	while (p != NULL)
    	{
    		n = p->next;
    		free(p->word);
    		free(p);
    		p = NULL;
    		p = n;
    	}
    	printf("\n");
    	return 0;
    }

  8. #8
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    > head->word = "List:";

    While this is not wrong, you free this string which is probably where the "corruption" problem originates. You cannot free strings pointed-to like this. Decide what you want to do here: either you eschew allocating head->word and treat the head differently, or you treat the head like every other node, copying into head->word, etc.

  9. #9
    Registered User
    Join Date
    Sep 2009
    Posts
    61
    Thanks whiteflags!

    The error is solved, but it still doesn't want to print the list. To see what was wrong I added some lines. Now I get a segmentation fault when I have finished the list input. The computer doesn't like "printf("\n%s",p->word);". But I can't understand why...


    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    char string[10];
    struct node
    {
    	char *word;
    	struct node *next;
    };
    
    int main(void)
    {
    
    	struct node* head = NULL;
    	struct node* p = NULL;
    	struct node* n = NULL;
    	
    	
    	head = malloc(sizeof(struct node));
    	head->word = malloc(10);
    	head->word = NULL;
    	n = head->next;
    	
    	while ( string[0] !='q' ) 
    	{
    		p = n;
    		printf("\nInput string:\n");
    		scanf("%s", string);
    		p = malloc(sizeof(struct node));
    		p->word = malloc(10);
    		strcpy(p->word, string);
    		n = p->next;
    	}
    	
    	
    	p = head->next;
    	printf("\n%s",p->word);
    	p = p->next;
    	while(p!=NULL)
    	{
    		printf("\n%s",p->word);
    		p = p->next;
    	}
    
    	n = head->next;
    	free(head->word);
    	free(head);
    	p = n;
    	while (p != NULL)
    	{
    		n = p->next;
    		free(p->word);
    		free(p);
    		p = NULL;
    		p = n;
    	}
    	printf("\n");
    	return 0;
    }

  10. #10
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    That basically means we haven't made any progress.

    struct node* p = NULL;
    struct node* n = NULL;

    These need real names.

    Also you can't build a list like you're going to delete it. There's a lot of similarity between the delete and insertion parts of the program. It's more like this:
    Code:
    p = head; /* start at the head */
    
    while (string[0] != 'q') 
    {
      printf("enter string: \n");
      scanf("%9s" , string);
    
       n = malloc(sizeof *n);
    
       /* fill in your node's fields */
       n->word = malloc(sizeof string);
       strcpy(n->word , string);
       n->next = NULL;
    
      /* connect your node */
      p->next = n;
      p = p->next; /* p == n here, so that the next node is after n */
    }
    See how one pointer holds the new node, and the other just keeps track of the place? When the loop quits you should have a good list starting from head and ending at NULL.

    You might also want to look at the head again. Right now you've leaked head->word's memory.

  11. #11
    Registered User
    Join Date
    Sep 2009
    Posts
    61
    Thanks a lot!

    Now I know how to deal with linked lists.

    Here is the final code. Perhaps it can be helpful for other newbies.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    char string[10];
    struct node
    {
    	char *word;
    	struct node *next;
    };
    
    int main(void)
    {
    
    	struct node* head = NULL;	
    	struct node* p = NULL;
    	struct node* n = NULL;
    
    	head = malloc(sizeof *head);
    	head->next = malloc(sizeof(struct node));
    	p = head->next;
    	p->word = malloc(sizeof string);
    			
    	while (string[0] != 'q') 
    	{
    		printf("Enter string:\n");
    		scanf("%s" , string);
    
    		strcpy(p->word, string);
    		p->next = malloc(sizeof(struct node));
    		n = p->next;
    		n->word = malloc(sizeof string);
    		p=n;
    	}
    	
    	printf("The string list:\n");
    	p = head->next;
    	while(p!=NULL)
    	{
    		printf("%s\n",p->word);
    		p = p->next;
    	}
    
    	p = head->next;
    	free(head->word);
    	free(head);
    	head = NULL;
    	while (p != NULL)
    	{
    		n = p->next;
    		free(p->word);
    		free(p);
    		p = NULL;
    		p = n;
    	}
    	printf("\n");
    	return 0;
    }

  12. #12
    DESTINY BEN10's Avatar
    Join Date
    Jul 2008
    Location
    in front of my computer
    Posts
    804
    Have you executed the code and is it working properly?
    HOPE YOU UNDERSTAND.......

    By associating with wise people you will become wise yourself
    It's fine to celebrate success but it is more important to heed the lessons of failure
    We've got to put a lot of money into changing behavior


    PC specifications- 512MB RAM, Windows XP sp3, 2.79 GHz pentium D.
    IDE- Microsoft Visual Studio 2008 Express Edition

  13. #13
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    string[10] doesnt have to be global. I mean, you only have one function, main(). The global scope of string[10] wouldn't serve anything.
    Not that it is wrong, but global variables should be avoided. So when there is no reason to make a variable global, don't

  14. #14
    Registered User
    Join Date
    Dec 2009
    Posts
    2
    I'm learning liked lists in C too, I see you got it how linked lists work so here is how I would go about solving that problem, I used 3 pointers because that is how I'm used to code linked lists in C.
    Hope that helps.

    Code:
    /* 
     * File: liked.c
     * -------------
     * Creates a linked list and prints the strings
     * entered by the user.
     */
    
    #include <stdlib.h>
    #include <stdio.h>
    
    typedef struct node{
            char word[10];
            struct node *next;
            }NODE;
            
    int main(void)
    {
        NODE *head = NULL;
        NODE *prev,*curr;
        char str[10];
        
        printf("[ENTER TO QUIT] String: ");
        
        while( gets(str) != NULL && str[0] != '\0' )
        {
               curr = (NODE*) malloc(sizeof(NODE));
               
               //if head == NULL so it is the first position
               if ( head == NULL )
               head = curr;
               else
               //prev->next = current position
               prev->next = curr;
               
               //set the curr pointer to be the end
               //of the linked list
               curr->next = NULL;
               prev = curr;
               
               strcpy(curr->word,str);
               printf("String: ");
        }
        
        curr = head;
        
        // there is a null at the end of the linked list
        // so we can do while != NULL
        
        while ( curr != NULL )
        {
              printf("%s\n",curr->word);
        // set the current position to be the next position
              curr = curr->next;
        }
        
        return 0;
    }

  15. #15
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    Code:
        while( gets(str) != NULL && str[0] != '\0' )
    Yikes! Please don't ever use or encourage the use of the gets() function. Use fgets() instead.
    If you understand what you're doing, you're not learning anything.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. C++ Linked list program need help !!!
    By dcoll025 in forum C++ Programming
    Replies: 1
    Last Post: 04-20-2009, 10:03 AM
  2. Following CTools
    By EstateMatt in forum C Programming
    Replies: 5
    Last Post: 06-26-2008, 10:10 AM
  3. Reverse function for linked list
    By Brigs76 in forum C++ Programming
    Replies: 1
    Last Post: 10-25-2006, 10:01 AM
  4. Problem with linked list ADT and incomplete structure
    By prawntoast in forum C Programming
    Replies: 1
    Last Post: 04-30-2005, 01:29 AM
  5. singly linked list
    By clarinetster in forum C Programming
    Replies: 2
    Last Post: 08-26-2001, 10:21 PM