Thread: Addind An Item To a Linked List

  1. #1
    Registered User
    Join Date
    Jul 2016
    Posts
    7

    Addind An Item To a Linked List

    Adding an item to a linked list is something I seem to have no end of trouble implementing. I can understand the concept but if anyone can help me where I'm going wrong that wouldbe appreciated. I know it's something to do with adding the item or probably returning the pointers because that's where the segmentation fault 11 is. My code is below.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    /*The structure to store the data and the pointer to the next item in the list.*/
    typedef struct item{
        char *name;
        char *shelf;
        int stock;
        double price;
        struct item *next;}item;
    item *addtoend(item *start, item *current){
        char *input=malloc(25);
        printf("Enter data separated by tabs.\n");
    /*Get the user input then parse it into the separate data pieces.*/
        fgets(input, 25, stdin);
        sscanf(input, "%s\t%s\t%d\t%lf", current->name, current->shelf, &current->stock, &current->price);
        free(input);
    /*If the list is empty set the start pointer to the current pointe and start's next pointer to NULL. Otherwise set current's next pointer to start.*/
        if(start==NULL){
            start=current;
            start->next=NULL;}
        else{
            current->next=start;}
        return current;}
        int main(){
    /*The start and current pointers point to the start of the list and the current item respectively.*/
        item *start=malloc(sizeof(item)), *current=malloc(sizeof(item));
        char *command=malloc(15);
        printf("welcome to the shop.\n");
    /*Check that the program really did get the memory.*/
    if(start!=NULL){
            while(fgets(command, 15, stdin)){
                if(strncmp(command, "addtoend", 8)==0){
                    addtoend(start, current);
                    printf("%s added to the %s shelf.\n", current->name, current->shelf);}
                else if(strncmp(command, "quit", 4)==0){
    /*Free the pointers that were dynamically allocated memory earlier.*/
                    free(start);
                    free(current);
                    free(command);
                    printf("Exiting ...\n");
                    break;}}}
        else{
            printf("Memory could not be allocated!\n");}
        printf("Thank you for visiting the shop.\n");
        return 0;}
    The output from gdb when I run it on the linode is here.
    Starting program: /root/shop
    welcome to the shop.
    addtoend
    Enter data separated by tabs.
    bilk dairy 123 0.89
    (null) added to the (null) shelf.
    quit
    Exiting ...
    Thank you for visiting the shop.
    [Inferior 1 (process 31117) exited normally]
    The thing I don't understand as well is why does it say inferior when the program exits apparently normally.

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    I suggest that you practice linked list insertion with a simpler node, e.g.,
    Code:
    typedef struct node
    {
        int value;
        struct node *next;
    } node;
    When you are familiar with various patterns of insertion into a linked list, you can then declare:
    Code:
    typedef struct item
    {
        char *name;
        char *shelf;
        int stock;
        double price;
    } item;
    Then modify the node to:
    Code:
    typedef struct node
    {
        item value;
        struct node *next;
    } node;
    Of course, assigning the value and getting the value will have to change too, but then you can provide an interface of functions for creating, retrieving the members of, updating the members of, and destroying an item. Since you are reasonably certain your linked list code works, you don't have to worry about debugging it at the same time as you implement this interface.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Jul 2016
    Posts
    7
    I'm writing in c rather than c++. The reason I put the debugger output here was because I've tried posting in other places and got told to use a debugger, so of course everyone's sending me round in ceicles when it's probably only a couble of lines of the code I probably need to correct.

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    > The thing I don't understand as well is why does it say inferior when the program exits apparently normally.
    It's like parent / child being compared to superior (the debugger) and inferior (the program being debugged)
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by harmony
    I'm writing in c rather than c++.
    Yes, and hence my code snippet is in C, not C++. What made you think that C++ is involved?

    Quote Originally Posted by harmony
    The reason I put the debugger output here was because I've tried posting in other places and got told to use a debugger, so of course everyone's sending me round in ceicles when it's probably only a couble of lines of the code I probably need to correct.
    It is hard to even read your code because you did not format it properly. For example:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    /*The structure to store the data and the pointer to the next item in the list.*/
    typedef struct item {
        char *name;
        char *shelf;
        int stock;
        double price;
        struct item *next;
    } item;
    
    item *addtoend(item *start, item *current) {
        char *input = malloc(25);
        printf("Enter data separated by tabs.\n");
        /*Get the user input then parse it into the separate data pieces.*/
        fgets(input, 25, stdin);
        sscanf(input, "%s\t%s\t%d\t%lf", current->name, current->shelf, &current->stock, &current->price);
        free(input);
        /*If the list is empty set the start pointer to the current pointe and start's next pointer to NULL. Otherwise set current's next pointer to start.*/
        if (start == NULL) {
            start = current;
            start->next = NULL;
        } else {
            current->next = start;
        }
        return current;
    }
    
    int main() {
        /*The start and current pointers point to the start of the list and the current item respectively.*/
        item *start = malloc(sizeof(item)), *current = malloc(sizeof(item));
        char *command = malloc(15);
        printf("welcome to the shop.\n");
        /*Check that the program really did get the memory.*/
        if (start != NULL) {
            while (fgets(command, 15, stdin)) {
                if (strncmp(command, "addtoend", 8) == 0) {
                    addtoend(start, current);
                    printf("%s added to the %s shelf.\n", current->name, current->shelf);
                } else if (strncmp(command, "quit", 4) == 0) {
                    /*Free the pointers that were dynamically allocated memory earlier.*/
                    free(start);
                    free(current);
                    free(command);
                    printf("Exiting ...\n");
                    break;
                }
            }
        } else {
            printf("Memory could not be allocated!\n");
        }
        printf("Thank you for visiting the shop.\n");
        return 0;
    }
    But my point is that you have mistakes that have nothing to do with linked list insertion per se. Basically, you allocated space for the nodes, but you failed to allocate space for the strings. Take a look:
    Code:
    char *input = malloc(25);
    printf("Enter data separated by tabs.\n");
    /*Get the user input then parse it into the separate data pieces.*/
    fgets(input, 25, stdin);
    sscanf(input, "%s\t%s\t%d\t%lf", current->name, current->shelf, &current->stock, &current->price);
    free(input);
    In the sscanf call, you assume that space has been allocated for current->name and current->shelf, but now with proper formatting, a quick check of main shows that you never did allocate space for them. Instead, you did unnecessary complication with the malloc(25) call (and likewise for command) when you could have written:
    Code:
    char input[25] = "";
    Furthermore, you don't specify a field with, i.e., you use "%s" instead of say "%15s", so your sscanf call is vulnerable to buffer overflow.

    Hence, you should work with int objects instead of a struct object value for your linked list node first, and later come back to deal with nodes containing struct objects.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  6. #6
    Registered User
    Join Date
    Jul 2016
    Posts
    7
    I know that, because I don't know how many characters the user will type in but had to dynamically allocate it to something so if it's longer than that it can just get more memory or if it's shorter the program doesn't have to use so much memory.

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by harmony
    I know that, because I don't know how many characters the user will type in but had to dynamically allocate it to something so if it's longer than that it can just get more memory or if it's shorter the program doesn't have to use so much memory.
    That is a valid concern, but the thing is that you did not allocate memory at all. I suggest that you put aside your current program to experiment on reading an arbitrarily long line as a string and parsing it for "words" and numbers. For reading the line, you can either code a loop with fgets (i.e., keep looping and appending to the string stored in a dynamic array until the newline is found at the end of the current input), or you might be able to use the non-standard but POSIX standard getline function. For parsing, you probably cannot use sscanf because you want the "words" to be arbitrarily long as well. This means that you may have to say, use strtok four times, copying the "words" after allocating just enough space for them (remember the null character too), and use strtol and strtod to convert the tokens to numbers.

    I stress that this experimenting should be done as a separate project. You can eventually say, move the finished work into a function that you then copy and use in your linked list program, but trying to do both at the same time when you are in the process of acquring the skill to do so is going to be a painful ride.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  8. #8
    Registered User
    Join Date
    Jul 2016
    Posts
    7
    I know my user input isn't great, but that I'll come back to later I think. I'm more interested in fixing my linked list stuff at the minut so I can improve at that.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. how to add new item at the end of linked list
    By raghu_equinox in forum C Programming
    Replies: 3
    Last Post: 10-11-2006, 01:00 PM
  2. how to remove last item of linked list please
    By raghu_equinox in forum C Programming
    Replies: 6
    Last Post: 10-11-2006, 03:04 AM
  3. add linked list item to the top
    By xion in forum C++ Programming
    Replies: 8
    Last Post: 02-12-2005, 08:59 AM
  4. Removing an item from a linked list
    By Lone in forum C++ Programming
    Replies: 2
    Last Post: 11-30-2004, 01:32 PM
  5. delete item from linked list
    By lambs4 in forum C Programming
    Replies: 2
    Last Post: 03-28-2003, 11:06 AM

Tags for this Thread