Thread: List of lists/ Reading from File/ Segmentation Error

  1. #1
    Registered User
    Join Date
    Dec 2015
    Posts
    4

    Unhappy List of lists/ Reading from File/ Segmentation Error

    Hi!
    I have to do a multi list and read words from a file, like this: List of lists/ Reading from File/ Segmentation Error-capturar-png
    And I'm going nuts with it
    It's my first time implementing a code like this and I've spent like 10 hours + with the segmentation error...

    Before posting the code, 2 things:
    InfoSize might have something to do with it. You see, it's a data struct end of term code, so I'm using my professor's code as a kind of base. He always uses InfoSize but never to read characters. I tried changing it a bit but couldn't really do much since I got tons of errors.
    Second, the code was in Portuguese, I just translated it so excuse me if the variables aren't that cool in English.

    Also, it might seem confusing as to why I did some stuff in a weird way instead of going simple, that is probably because I received the segmentation fault so many times and in so many different places that I had to change it a lot, so it became a little weird.
    Struct:
    Code:
    typedef struct noLDDE
    {void *information;
     struct noLDDE *next;
     struct noLDDE *ant;
     struct noLDDE *right; 
    }NoLDDE,*pNoLDDE;
    
    typedef struct LDDE
    { int InfoSize;
      pNoLDDE list;
    }LDDE;
    Code:
    int insertFunction(pLDDE p, void *word, int line_number)
    {
        pNoLDDE temp, aux, aux2, aux3;
        int i = 0;
        int ret = FRACASSO;
                aux = p->list; //first node
                while (i != line_number) //till it finds the corresponding node -on the main list-
                {
                    if (aux == NULL)
                    {
                        insertInTheEnd(p, word);
                        //using this to push another node in the main list
                        }
    
                    if (i == 0){
                        aux3 = p->list;
                        aux = aux3->next;
                        i++;
                    }
                    else{
                        aux3 = aux3->next;
                        aux = aux3->next;
                        i++; //all this is just to find the node = to the line I should insert
                    }
                }
    
                if ((temp = (pNoLDDE)malloc(sizeof(NoLDDE))) != NULL) //malloc for the node --secondary list-- 
                {
                    if ((temp->information = (void *)malloc(p->InfoSize)) != NULL)
                    {
                        memcpy(temp->information, word, p->InfoSize);
                        
                        temp->next = NULL;
    
    
                        if (aux3->right == NULL)  //if there is no element in the secondary list
                        {
                            aux3->right = temp;
                            temp->ant = NULL;
                        }
                        else
                        {
                            aux3 = aux3->right;
                            while (aux3->next != NULL){ //finding the last one to insert in the end
                                aux3 = aux3->next;
                            }
                            
                            aux3->next = temp;
                            temp->ant = aux3;
                        }
                        ret = SUCESSO;
                    }
                }
                else
                    free(temp);
    
        return ret;
    
    
    
    }
    
    /*************** INSERE NO FINAL ***************/
    int insertInTheEnd(pLDDE p, void *word)
    {     pNoLDDE temp, aux;
        int ret = FRACASSO;
        if((temp=(pNoLDDE)malloc(sizeof(NoLDDE)))!= NULL)
        {
            if ((temp->information = (void *)malloc(p->InfoSize)) != NULL)
            {
                memcpy(temp->information, word, p->InfoSize);
                temp->next = NULL;
                 temp->right = NULL;
                
    
             if (p->list == NULL)
             {
                p->list = temp;
                temp->ant=NULL;
    
             }
             else
             {
                aux = p->list;
                while (aux->next != NULL)
                    aux = aux->next;
                aux->next = temp;
                temp->ant=aux;
             }
                 ret = SUCESSO;
         }
         else
              free(temp);
       }
       return ret;
    }
    
    int create(ppLDDE pp, int InfoSize)
    {   int ret = FRACASSO;
        if(((*pp)=(pLDDE)malloc(sizeof(LDDE)))==NULL)
            ret = FRACASSO;
        else
        {
            (*pp)->list = NULL;
            (*pp)->InfoSize = InfoSize;
                ret = SUCESSO;
        }
            return ret;
    
    }
    
    
    void printtext(pLDDE p){
        pNoLDDE temp, aux;
        if (p->list == NULL){
            printf("Empty list!");
            return;
        }
        else{
            aux = p->list;
            temp = aux->right;
    
    
            while (aux != NULL){ //loop on the main list, each node is a line
                
                while (temp != NULL){ //loop on the words list
                    printf("%s ", (char *)temp->information);
                    temp = temp->next;
    
                }
                aux = aux->next;
                temp = aux->right;
                printf("\n");
            }
        }
    
        
    }
    
    
    int main()
    {
        pLDDE pList;
        
    
        FILE *file;
        char line[1000];
        create(&pList, sizeof(char*));
        file = fopen("file.txt", "r");
        int line_number = 1;
        if (file != NULL){
    
    
            while (fgets(line, 1000, file) != NULL){ //while it is able to read
    
                char *word = strtok(line, " ");
                while (word != NULL){ //until it gets to the end of the line
                                    
                    insertFunction(pList, word, line_number); 
                    word = strtok(NULL, " ");
                }
                line_number++;
                
            }
        }
    
        fclose(file);
        printtext(pList);
        return 0;
    }
    And here is the gdb:


    Sorry for not making it easy by posting just a part of the code, but I'm really out of options right now, kinda desperate actually.
    Thanks~~
    Attached Images Attached Images List of lists/ Reading from File/ Segmentation Error-2-png 

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,667
    > ,*pNoLDDE;
    The first thing I would suggest you do is drop this idea of creating a separate name for each pointer type.
    By the time you start to add the qualifiers 'const' and 'volatile' into the mix, you end up with a god-awful mess before you know what's happened.

    > (temp->information = (void *)malloc(p->InfoSize)
    The next thing to do is drop the casting of malloc return result.
    FAQ > Casting malloc - Cprogramming.com
    If you're really compiling this C program with a C compiler, you don't need the cast if you're doing it properly.
    And if you do get an error message, then the lack of the cast will show up the error rather than suppressing it.

    > memcpy(temp->information, word, p->InfoSize);
    Your thoughts on infosize are essentially correct, which is why all the code is broken.

    > create(&pList, sizeof(char*));
    You may have noticed that there are an awful lot of strings with only 4 characters, which is coincidentally the size of a pointer on your machine.
    What is more, memcpy() will NOT put the \0 at the end of the string, so you see garbage after each 4-character string.

    Eventually of course, your luck runs out on the garbage printing, and you get a segfault.

    Your task is to figure out how to copy a string properly into your data structure.
    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.

  3. #3
    Registered User
    Join Date
    Dec 2015
    Posts
    4
    Thank you very much for your reply.
    About the *pNoLDDE thing, I'll take that to heart.
    I changed the malloc, but what about here?
    if(((*pp)=(pLDDE)malloc(sizeof(LDDE)))==NULL)
    Should it be like this?
    if(((*pp) = malloc(sizeof(**pp))) == NULL)
    As for the memcpy, I'm using strtok and I thought it would do the trick for the \0, gonna have to figure it out why it's not doing it.
    I'm checking this, https://en.wikipedia.org/wiki/C_data_types
    on Pointer Types, looking for something to change the int in InfoSize.

  4. #4
    Registered User
    Join Date
    Dec 2015
    Posts
    4
    Oh and the code now kinda "works"
    I fixed this,
    Code:
    char InfoLine[15];
    create(&pList, sizeof(InfoLine));
    But it still gives me the segmentation fault, do you still think it is because of the \0?
    You see, I'm asking you to confirm because it is not printing garbage with the words:

    List of lists/ Reading from File/ Segmentation Error-capturar-png

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,667
    Well if in gdb you do something like
    print aux
    you'll either find it's NULL or a garbage pointer.

    You then work back through the code to figure out where it should have been set up, and figure out why it isn't being set up.
    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.

  6. #6
    Registered User
    Join Date
    Dec 2015
    Posts
    4

    Red face

    Salem, I haven't seen a code compiling without errors for a few days now, thank you so much for your help.
    It finally worked
    Here's what I changed (in the printtext function):
    Code:
     if (aux->next != NULL)
                {
                    aux = aux->next;
                    temp = aux->right;
                    printf("\n");
                }
    I learned a lot today and hopefully I'll be able to finish all this easily by tomorrow :D

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Print linked list: Error - segmentation fault
    By deathmetal in forum C Programming
    Replies: 8
    Last Post: 08-10-2015, 01:39 PM
  2. Reading a file to linked lists?!
    By orangePeel in forum C Programming
    Replies: 7
    Last Post: 06-21-2013, 01:20 AM
  3. Replies: 5
    Last Post: 04-10-2012, 02:31 PM
  4. link list, segmentation error
    By bernhj in forum C Programming
    Replies: 4
    Last Post: 10-16-2007, 09:02 PM
  5. Reading file into linked lists
    By bcianfrocca in forum C++ Programming
    Replies: 2
    Last Post: 02-28-2005, 04:12 PM