Thread: Segmantation fault of the code: compiles but wrong output

  1. #1
    Registered User
    Join Date
    Dec 2010
    Posts
    20

    Question Segmantation fault of the code: compiles but wrong output

    Hi,

    I got this code done and have got some problems with output:

    insert
    Code:
    #include <stdio.h>
    #include <stddef.h>
    #include <stdlib.h>
    #include <string.h>
    
    /*********************************/
    /* structure EastDevon*/
    
    struct EastDevon {
        char party[2];
        char lastName[31];
        char firstName[31];
        unsigned int votes[4];
        struct EastDevon *nextresult;
        };
    typedef struct EastDevon RESULT;
    
    /* function prototypes */
    
    RESULT ProcessFile (FILE *);
    void AddResult     (RESULT *, char*, char *, char *, unsigned int, unsigned int, unsigned int, unsigned int);
    void PrintList (RESULT *);
    
    /* main function */
    
    int main() {
        FILE *fin;
        RESULT root;
        if ((fin = fopen("EastDevon.txt", "r")) == NULL)
        {
        printf ("Unable to read file\n");
        return EXIT_FAILURE;
        }
        
        root = ProcessFile(fin);
        PrintList(&root);
        
        fclose(fin);
        return EXIT_SUCCESS;
    }
    
    /*Reads the file pointed to by fin and constructs a linked list structure,
    /* with root as the root result of the tree;     */
    
    RESULT ProcessFile (FILE *fin){
        RESULT root;
        char cParty[2];
        char cLastName[31];
        char cFirstName[31];
        unsigned int C1Votes;
        unsigned int C2Votes;
        unsigned int C3Votes;
        unsigned int C4Votes;
        int count = 0;
        
        while (fscanf (fin, "%s%s%s%d%d%d%d", cParty, cLastName, cFirstName, &C1Votes, &C2Votes, &C3Votes, &C4Votes) == 4)
      {
        count++;
        if (count == 1)
        { 
            strcpy(root.party, cParty);
            strcpy(root.lastName, cLastName);
            strcpy(root.firstName, cFirstName);
            root.votes[0]= C1Votes;
            root.votes[1]=C2Votes;
            root.votes[2]=C3Votes;
            root.votes[3]=C4Votes;
            root.nextresult = NULL; }
        else
          AddResult (&root, cParty, cLastName, cFirstName, C1Votes,C2Votes,C3Votes,C4Votes);
      }
        return root;
    }
    
    
    /*Add a new result to the linked list whose root result is in the first
    /*parameter passed to the function    */
    
    
    void AddResult  (RESULT *root,
            char *cParty,
            char *cLastName,
            char *cFirstName,
             unsigned int C1Votes,
             unsigned int C2Votes,
             unsigned int C3Votes,
             unsigned int C4Votes)
    {
        RESULT *result = root;
        RESULT *newresult = (RESULT *)malloc(sizeof(RESULT));
        
        if (newresult == NULL)
        { 
            printf("Unable to allocate memory\n");
            exit(EXIT_FAILURE);
        }
        
        strcpy(newresult->party, cParty);
        strcpy(newresult->lastName, cLastName);
        strcpy(newresult->firstName, cFirstName);
        newresult->votes[0] = C1Votes;
        newresult->votes[1]=C2Votes;
        newresult->votes[2]=C3Votes;
        newresult->votes[3]=C4Votes;
        
        while (result->nextresult !=NULL)
            result = result->nextresult;
        
        result->nextresult = newresult;
    }
    
    /* print all the results in the linked list */
    
    void PrintList (RESULT *result)
    {
        if (result == NULL)
        return;
        
        printf("RESULTS LIST REPORT FOR:EAST DEVON:/n %s:%s:%s:%08d %08d %08d %08d\n", result->party, result->lastName,
               result->firstName, result->votes[0], result->votes[1], result->votes[2], result->votes[3]);
        PrintList(result->nextresult);
    
    }
    The code compiles and runs, but outputing smth different from what it should and giving segmantation fault in the end:

    Terminal:
    RESULTS LIST REPORT FOR:EAST DEVON:/n mith:th:���I�:13520032 -1075779400 02021020 134515042
    RESULTS LIST REPORT FOR:EAST DEVON:/n r:EastDevon.txt:le:1952539503 1701650533 2037542765 00000000
    Segmentation fault

    Here is the actual format it should be outputed in on the screen from a text file(the text file contains the same info):

    ASmith Angela 214003
    CJones Brian 32867
    BParker-Bowles Philip 546382
    GEvans Charlotte 34869837

    Any idea what is wrong?

  2. #2
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    Your data file looks wrong based on how you're trying to read it. Assuming your code is conforming to the specification, the first column in the file should be a single byte, e.g.:
    A Smith Angela 214003

    Otherwise you're reading ASmith into cParty which is not large enough to hold it.

    The last column looks like it should be 4 separate numbers, too. The way you have it, you're only reading one number (and only expecting to, for some reason, based on the fact that you're checking fscanf()'s return value against 4), but you are treating C2Votes, C3Votes, and C4Votes as if they contain useful values, which they cannot.

    In AddResult(), you need to set newresult->nextresult to NULL.

    Smaller issues: you're nesting comments (you cannot have a /* inside of a comment), and you're reading unsigned integers with %d, when you should use %u.

    But the main problem is the data is in the wrong format.

  3. #3
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    #1.
    Code:
    RESULT ProcessFile (FILE *fin){
    
       ...    
       while (fscanf (fin, "%s%s%s%d%d%d%d", cParty, cLastName, cFirstName, &C1Votes, &C2Votes, &C3Votes, &C4Votes) == 4)
      {
    You're reading in 7 values but comparing it to 4?



    #2
    Code:
    void AddResult  (...)
    {
        ...
    
        RESULT *newresult = (RESULT *)malloc(sizeof(RESULT));
    You shouldn't cast the return value of calls to malloc. malloc returns a void * type that can be safely assigned to your RESULT pointer without the need for a cast.



    #3. You do not call free to clean up your dynamic memory allocations.



    #4
    Code:
    void AddResult  (...)
    {
        ...
        
        strcpy(newresult->party, cParty);
        strcpy(newresult->lastName, cLastName);
        strcpy(newresult->firstName, cFirstName);
        newresult->votes[0] = C1Votes;
        newresult->votes[1]=C2Votes;
        newresult->votes[2]=C3Votes;
        newresult->votes[3]=C4Votes;
        
        newresult->nextresult = NULL;  /* Added by me! */
    
        while (result->nextresult !=NULL)
            result = result->nextresult;
        
         result->nextresult = newresult;
    }
    You seem to have neglected the initialization of one of your struct's member variables (see above part that I've added in blue).


    Start with those and see what you get.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  4. #4
    Registered User
    Join Date
    Dec 2010
    Posts
    20
    @cas:
    Thanks a lot. This helped a lot, I changed the data file with space after party and it worked, I got this:

    RESULTS LIST REPORT FOR:EAST DEVON:/n A:Smith:Angela:00214003 00000003 138608640 00135168
    RESULTS LIST REPORT FOR:EAST DEVON:/n C:Jones:Brian:00032867 00000003 138608640 00135168
    RESULTS LIST REPORT FOR:EAST DEVON:/n B:Parker-Bowles:Philip:00546382 00000003 138608640 00135168
    RESULTS LIST REPORT FOR:EAST DEVON:/n G:Evans:Charlotte:34869837 00000003 138608640 00135168

    But here are 2 problems: 1)I need RESULT LIST REPORT FOR: EAST DEVON to be written just once at the top
    2) What are the other numbers are appeared after vote numbers? how to get rid of them?

    Can I ask you to direct me how to print all the results in the linkedList by order: i.e. by last name? I would be very thankfull if you show me the right direction of how to do it. Thanks a lot.

  5. #5
    Registered User
    Join Date
    Dec 2010
    Posts
    20
    @hk_mp5kpdw:

    Great, i did change it, but why terminal shows these extra numbers at the end:

    RESULTS LIST REPORT FOR:EAST DEVON:/n A:Smith:Angela:00214003 00000003 153227264 00135168
    RESULTS LIST REPORT FOR:EAST DEVON:/n C:Jones:Brian:00032867 00000003 153227264 00135168
    RESULTS LIST REPORT FOR:EAST DEVON:/n B:Parker-Bowles:Philip:00546382 00000003 153227264 00135168
    RESULTS LIST REPORT FOR:EAST DEVON:/n G:Evans:Charlotte:34869837 00000003 153227264 00135168

    And why RESULT LIS REPORT FOR:EAST DEVON is printed on front of every candidate. I need it just once at the top?

  6. #6
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by SalamuB View Post
    @hk_mp5kpdw:

    Great, i did change it, but why terminal shows these extra numbers at the end:

    RESULTS LIST REPORT FOR:EAST DEVON:/n A:Smith:Angela:00214003 00000003 153227264 00135168
    RESULTS LIST REPORT FOR:EAST DEVON:/n C:Jones:Brian:00032867 00000003 153227264 00135168
    RESULTS LIST REPORT FOR:EAST DEVON:/n B:Parker-Bowles:Philip:00546382 00000003 153227264 00135168
    RESULTS LIST REPORT FOR:EAST DEVON:/n G:Evans:Charlotte:34869837 00000003 153227264 00135168

    And why RESULT LIS REPORT FOR:EAST DEVON is printed on front of every candidate. I need it just once at the top?
    Because it's inside your loop.

  7. #7
    Registered User
    Join Date
    Dec 2007
    Posts
    2,675
    And the newline character is '\n' not '/n', in case you failed to figure that out from it printing with each output.

  8. #8
    Registered User
    Join Date
    Dec 2010
    Posts
    20
    Got it, now everything compiles and works. Thank you very much guys. I really appreciate ur help.

    But now I need to print all the results by order(i.e. by lastName)? Could you help me with start?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. IDE for C embedded advanced editing
    By Undici77 in forum Tech Board
    Replies: 32
    Last Post: 01-16-2010, 05:17 PM
  2. What's wrong with my code?
    By x2x3i5x in forum C Programming
    Replies: 6
    Last Post: 09-28-2009, 11:52 AM
  3. Obfuscated Code Contest
    By Stack Overflow in forum Contests Board
    Replies: 51
    Last Post: 01-21-2005, 04:17 PM
  4. same code different output
    By kashifk in forum C Programming
    Replies: 4
    Last Post: 03-18-2003, 02:51 PM
  5. problems with output from code
    By simhap in forum C++ Programming
    Replies: 0
    Last Post: 10-08-2001, 12:43 PM