Thread: Segentation Fault

  1. #1
    Registered User
    Join Date
    Jan 2011
    Posts
    55

    Segentation Fault

    Hey guys/gals...In the following code I get a seg fault and cannot figure out why. I figure if I have a few more people looking around in the program for where it breaks it'd speed up the process.

    Here's the Code:

    Code:
    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    
    typedef struct data_struct record;
    typedef record *link;
    
    struct data_struct
    {
    int id;
    char fname[25];
    char lname[25];
    int height;
    int age;
    char bowlframes[25];
    int bowlscore;
    link next; 
    };
    
    link newrecord( int id1, char fname1[], char lname1[], int height1, int age1, char bowlframes1[], int bowlscore1)
    {
     link tmp;
     
     
     tmp = malloc( sizeof(record) );   //allocates a box with fname
    
     tmp->id = id1;
     
     strcpy(tmp->fname, fname1);
     
     strcpy(tmp->lname, lname1);
     
     tmp->height = height1;
     
     tmp->age = age1;
     
     strcpy(tmp->bowlframes, bowlframes1);
     
     tmp->bowlscore = bowlscore1;
     
     tmp->next = NULL;
     
     return tmp;      //returns the amount address of memory to the main
    }
    
    link insertrear ( link head, link p )
    {
     link tmp;
     if (head == NULL)
       head = p;
     else
       {
        tmp = head;
        while ( tmp->next != NULL )
          tmp = tmp->next;
    
          tmp->next = p;
        }
      return head;
     }
     
     void printstuff( link t )
     {
     link shift;
     
     shift = t;
     while (shift != NULL)
      {
        printf("ID: %d\n", shift->id);
    	printf("%s ", shift->fname);
    	printf("%s\n", shift->lname);
    	printf("Height: %d\n", shift->height);
    	printf("Age: %d\n", shift->age);
    	printf("Bowling Frames: %s\n", shift->bowlframes);
    	printf("Final Score: %d\n\n", shift->bowlscore);
    	shift = shift->next;
      }
     }
    
    
    int computescore(char scores[], int len)
    {
    
    
    
       
       char num = ' ';
       int frame[30];
       int b, total = 0;
       
    
    //Array storage
      
    
    for(b = 0; b < len; b++)
       {
       num = scores[b];
       
       if(num == 'X')
       {
       frame[b] = 10;
       total = frame[b] + total;
       }
       
       else if(num == '/')
       {
       frame[b] = 10 - frame[b-1];
       total = frame[b] + total;
       }
       
       else if(num >= '0' && num <= '9')
       {
       frame[b] = num - '0';
       total = frame[b] + total;
       }   
      else
       {
        b--;
       }
       }
       
    //Scores total with strike, spare rules
    
    /*for (y=0;y<x+1;y++)
       {
    
    if(frame[e] == 10)
       {
       total = total + 10 + scores[e+1] + scores[e+2];
       e = e + 1;
       }
    else if(scores[e] + scores[e+1] == 10)
       {
       total = total + 10 + scores[e+2];
       e = e + 2;
       }
    else if(scores[e] == -1)
       { 
       break;
       }
    else
       {
       total = total + scores[e] + scores[e+1];
       e = e + 2;
       }
       }
    */
    return total;
    
    }
    
    
    int main()
    {
    
    
    
     link L, p, q;
     int id, height, age, bowlscore, len, score1;
     char fname[30], lname[30], bowlframes[30];
     
    L = NULL; //pointer to NULL
    
    FILE *fp;
    
    fp = fopen("in.txt", "r");
    if (fp = NULL)
     {
      printf("Can't open file\n");
      exit(1);
     }
    
    fscanf(fp, "%d", &id);
    
    int N = 0;
    
    while( !feof(fp) )
    {
    
    	fscanf(fp, "%s", fname);
    	
    	fscanf(fp, "%s", lname);
    	
    	fscanf(fp, "%d", &height);
    	
    	fscanf(fp, "%d", &age);
    	
        fscanf(fp, "%s", bowlframes);
    	len = strlen( bowlframes );
    	score1 = computescore(bowlframes, len);
    	
    	p = newrecord(id, fname, lname, height, age, bowlframes, score1);
    	
    	L = insertrear( L, p);
    	N++;
        fscanf(fp, "%d", &id);
    	
    }
    
    printstuff( L );
    
    
    
    
    
    
    return 0;
    
    }
    And here's the file it's reading from

    Code:
    700
    Mary
    Smith
    66
    44
    XXXXXXXXXXXX 
    403 
    Michael
    Jordan
    78
    18
    23232323232323232323
    3
    04
    Not
    You
    75
    18
    3/3/3333333333333333
    In a quick summary...The is meant to read from the file (Line 1 being the id number, line 2 first name, 3 last name, 4 height, 5 age, and 6 a frame by frame bowling score). It also takes the bowling score frame by frame and computes the total score in the function 'computescore'. All of this is being put into a linked list inside a structure, thenthat structure is being linked to the next structure until the while loop reading in the data from the file hits the end of the file.

    It gives me a seg fault as I said before and I thought maybe another pair of eyes looking at would speed up the process a bit. Thanks in advance!!!

    ---------------

    -Duck-

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Do you know what speeds it up even more? Telling us actually what part of the program you were in when it gave you the segfault. What's the last thing you saw happen before it gave you a segfault? If you say "nothing", then start adding some printf lines around your code to figure out where it's crashing (lazy man's debugger).

    printf( "made it to point 1\n" );


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

  3. #3
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    Well, I see one problem right away:
    Code:
    if (fp = NULL)
    = is for assignment, == is for equality. Pay attention to your compiler warnings.
    If you understand what you're doing, you're not learning anything.

  4. #4
    Registered User
    Join Date
    May 2010
    Location
    Naypyidaw
    Posts
    1,314
    How many times do we have to tell not to use feof() to control the loop!!! Question 12.2

  5. #5
    Registered User
    Join Date
    Jan 2011
    Posts
    55
    The only reason I do it with feof is that is part of the instructions in writing the program. This is for a side project in my computer programming class and my instructor insisted on using feof.

  6. #6
    Registered User
    Join Date
    Sep 2008
    Location
    Toronto, Canada
    Posts
    1,834
    The file does not contain the sequence ID/name/name/height/age/frame. There is an extra number in there '3' or '04'.

  7. #7
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by DuckCowMooQuack View Post
    The only reason I do it with feof is that is part of the instructions in writing the program. This is for a side project in my computer programming class and my instructor insisted on using feof.
    You may want to acquaint him with the explaination of why that's a bad idea....

  8. #8
    Registered User
    Join Date
    Jan 2011
    Posts
    55
    Ha-ha, that will be fun. Tell my instructor he is wrong :P

    Ok so I've gotten all of it running up to one last error...

    Code:
    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    
    typedef struct data_struct record;
    typedef record *link;
    
    struct data_struct
     {
       int id;
       char fname[25];
       char lname[25];
       int height;
       int age;
       char bowlframes[25];
       int bowlscore;
       link next; 
     };
    
    link newrecord( int id1, char fname1[], char lname1[], int height1, int age1, char bowlframes1[], int bowlscore1)
     {
       link tmp;
     
       tmp = malloc( sizeof(record) );   //allocates a box with fname
    
       tmp->id = id1;
     
       strcpy(tmp->fname, fname1);
     
       strcpy(tmp->lname, lname1);
     
       tmp->height = height1;
     
       tmp->age = age1;
     
       strcpy(tmp->bowlframes, bowlframes1);
     
       tmp->bowlscore = bowlscore1;
     
       tmp->next = NULL;
     
       return tmp;      //returns the amount address of memory to the main
     }
    
    link insertrear ( link head, link p )
     {
       link tmp;
       if (head == NULL)
        head = p;
       else
       {
        tmp = head;
        while ( tmp->next != NULL )
         tmp = tmp->next;
         tmp->next = p;
       }
       return head;
     }
     
     void printstuff( link t )
     {
       link shift = t;
     
       while (shift != NULL)
       {
        printf("ID: %d\n", shift->id);
    	printf("%s ", shift->fname);
    	printf("%s\n", shift->lname);
    	printf("Height: %d\n", shift->height);
    	printf("Age: %d\n", shift->age);
    	printf("Bowling Frames: %s\n", shift->bowlframes);
    	printf("Final Score: %d\n\n", shift->bowlscore);
    	shift = shift->next;
       }
     }
    
    
    int computescore(char scores[], int len)
    {
       char num = ' ';
       int frame[30];
       int b, y, x, total;
       x = 0;
       
    for(b = 0; b < len; b++)
     {
       num = scores[x];
       
       if(num == 'X')
       {
        frame[x] = 10;
        x++;
       }
       
       else if(num == '/')
       {
        frame[x] = 10 - frame[x-1];
        x = x + 2;
       }
       
       else if(num >= '0' && num <= '9')
       {
        frame[x] = num - '0';
        x++;
       }
     }
       total = 0;
       x = 0;
       b = 0;
       
    for(b = 0; b < len; b++)
     {
       if(frame[x] == 10)
        {
    	 total = total + frame[x+1] + frame[x+2] + 10;
    	 x++;
    	}
       else if(frame[x] + frame[x+1] == 10)
        {
         total = total + 10 + frame[x+2];
    	 x = x + 1;
    	}
       else
        {
         total = total + frame[x] + frame[x+1];
         x = x + 2;
    	}
     }
    
    return total;
    
    }
    
    
    int main()
     {
    
    
    
       link L, p, q;
       int id, height, age, bowlscore, len, score1;
       char fname[30], lname[30], bowlframes[30];
     
       L = NULL; //pointer to NULL
    
       FILE *fp;
    
       fp = fopen("in.txt", "r");
       if (fp == NULL)
        {
         printf("Can't open file, check director.\n");
         exit(1);
        }
    
       fscanf(fp, "%d", &id);
    
       int N = 0;
       int u = 0;
    while( !feof(fp) )
     {
       fscanf(fp, "%s", fname);
    	
       fscanf(fp, "%s", lname);
    	
       fscanf(fp, "%d", &height);
    	
       fscanf(fp, "%d", &age);
    	
       fscanf(fp, "%s", bowlframes);
       len = strlen( bowlframes );
       
       score1 = computescore(bowlframes, len);
    
       p = newrecord(id, fname, lname, height, age, bowlframes, score1);
    	
       L = insertrear( L, p);
       N++;
       u++;
       fscanf(fp, "%d", &id);
    	
     }
       printstuff( L );
    
     return 0;
    
     }
    FILE:
    Code:
    700
    Mary
    Smith
    66
    44
    XXXXXXXXXXXX
    403 
    Michael
    Jordan
    78
    18
    23232323232323232323
    304
    Not
    You
    75
    18
    3/3/3333333333333333
    Specifically my computescore function is breaking...

    Code:
    int computescore(char scores[], int len)
    {
       char num = ' ';
       int frame[30];
       int b, y, x, total;
       x = 0;
       
    for(b = 0; b < len; b++)
     {
       num = scores[x];
       
       if(num == 'X')
       {
        frame[x] = 10;
        x++;
       }
       
       else if(num == '/')
       {
        frame[x] = 10 - frame[x-1];
        x = x + 2;
       }
       
       else if(num >= '0' && num <= '9')
       {
        frame[x] = num - '0';
        x++;
       }
     }
       total = 0;
       x = 0;
       b = 0;
       
    for(b = 0; b < len; b++)
     {
       if(frame[x] == 10)
        {
    	 total = total + frame[x+1] + frame[x+2] + 10;
    	 x++;
    	}
       else if(frame[x] + frame[x+1] == 10)
        {
         total = total + 10 + frame[x+2];
    	 x = x + 1;
    	}
       else
        {
         total = total + frame[x] + frame[x+1];
         x = x + 2;
    	}
     }
    
    return total;
    
    }
    It gives me a random number for total. I know this means it's accessing some random point in memory but I don't know why it goes outside of the array/string. Can anyone help me figure it out?

    Quote Originally Posted by nonoob View Post
    The file does not contain the sequence ID/name/name/height/age/frame. There is an extra number in there '3' or '04'.
    I accidently added a return character in there. The ID should be 304. I pressed enter somewhere along the line of programming.
    Last edited by DuckCowMooQuack; 03-25-2011 at 11:04 AM.

  9. #9
    Registered User
    Join Date
    Sep 2008
    Location
    Toronto, Canada
    Posts
    1,834
    You are using 'b' as the loop variable, but never using it inside the loop.
    This part seems flaky:
    Code:
    else if(num == '/')
       {
        frame[x] = 10 - frame[x-1];
        x = x + 2;
    - it looks like it will skip looking at an element.

  10. #10
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by DuckCowMooQuack View Post
    Ha-ha, that will be fun. Tell my instructor he is wrong :P
    Do it diplomatically -- basically approach it as though you want to learn more about when/why/how it's right or wrong. "I read online that using feof to control a loop was bad. I found the article at <give URL of explination>. Is the code you provided a special case where it works? Could you explain why this rule doesn't apply to the code we're using?"

  11. #11
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by DuckCowMooQuack View Post
    Ha-ha, that will be fun. Tell my instructor he is wrong :P
    It happens all the time. Think about it... if he's spending his time teaching C, it's unlikely he's doing any serious programming... it's pretty easy to get out of date on the most current improvements and standards. And WAY too easy to pass bad habits along to students.

    Look around these forums... there's a whole rash of people programming everything with global variables and void function(void) for everything... I'd bet real money it's all coming from one or two bad teachers.

    Also while you're surveying, take a look how many schools still teach Turbo C ... which is probably older than most of the students!

    Professors can and do get out of touch... And sometimes it takes a bit of "gentle advocacy" to get them caught up...

  12. #12
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Some comments:


    #1.
    Code:
    struct data_struct
     {
       int id;
       char fname[25];
       char lname[25];
       int height;
       int age;
       char bowlframes[25];
       int bowlscore;
       link next; 
     };
    
    ...
    
    char fname[30], lname[30], bowlframes[30];
     
    ...
       
    while(...)
    {
        fscanf(fp, "%s", fname);
    	
        fscanf(fp, "%s", lname);
    	
        fscanf(fp, "%d", &height);
    	
        fscanf(fp, "%d", &age);
    	
        fscanf(fp, "%s", bowlframes);
    
        ...
    A potential source of problems/confusion. Your character array variables in main have more space than what you can potentially store in the structs you will be allocating. The fscanf calls themselves do not limit the amount of characters that they read in and I would recommend taking this into account. What if a string read from the file has more than 30 characters?




    #2
    Code:
    typedef struct data_struct record;
    typedef record *link;
    Hiding/obfuscating pointers behind typedefs is generally frowned upon.



    #3
    Code:
    link newrecord( int id1, char fname1[], char lname1[], int height1, int age1, char bowlframes1[], int bowlscore1)
     {
       link tmp;
     
       tmp = malloc( sizeof(record) );   //allocates a box with fname
    You do not check that the malloc call succeeded. You simply assume it works. Also, it is generally better from a maintenance point of view to write the malloc call as such:
    Code:
    tmp = malloc( sizeof(*tmp) );   //allocates a box with fname
    ...that way, any changes to the type of variable tmp are automatically reflected without you needing to do anything. You don't have to go hunting down errors if you forget that you renamed tmp from a link (record*/struct data_struct*) to something else.



    #4
    Code:
    link newrecord( int id1, char fname1[], char lname1[], int height1, int age1, char bowlframes1[], int bowlscore1)
    {
        ...
     
        strcpy(tmp->fname, fname1);
     
        strcpy(tmp->lname, lname1);
    
        ...
     
        strcpy(tmp->bowlframes, bowlframes1);
        ...
    }
    Again, then strings you are passing in from main can safely have up to a length of 29 but what you are copying into can only safely store up to 24. You should only copy over what the destination arrays can safely store. If you do this in main while reading from the file - only read in strings up to 24 characters long (plus the null terminator) - then you don't have to do anything here because you'd be assured that the strings are already of the correct size. But, your differing array sizes seem to only compound the potential problem that exists.

    #5
    Ha-ha, that will be fun. Tell my instructor he is wrong :P
    Yes, a good teacher is open to not only teaching his students but being taught by them as well in return. Your teacher is demonstrating poor coding practices and expecting the students to learn such things. Be nice about it... but do tell him.
    "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

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. weird seg fault
    By Vermelho in forum C Programming
    Replies: 3
    Last Post: 05-10-2008, 08:27 PM
  2. Segmentation fault
    By NoUse in forum C Programming
    Replies: 4
    Last Post: 03-26-2005, 03:29 PM
  3. Locating A Segmentation Fault
    By Stack Overflow in forum C Programming
    Replies: 12
    Last Post: 12-14-2004, 01:33 PM
  4. Segmentation fault...
    By alvifarooq in forum C++ Programming
    Replies: 14
    Last Post: 09-26-2004, 12:53 PM
  5. segmentation fault and memory fault
    By Unregistered in forum C Programming
    Replies: 12
    Last Post: 04-02-2002, 11:09 PM