Thread: unknown seg fault reason.

  1. #1
    Noob of C
    Join Date
    Apr 2008
    Location
    Melbourne
    Posts
    10

    unknown seg fault reason.

    hi, i'm new to this forums howevery i hope someone can help me out here...

    i'm writing a program for an assignment actually, however i'm unable to debug this segmentation fault...

    excuse the stubs i used for checking and bad programming conventions...

    but heres the code.

    its not complete btw... i'm just trying to fix the seg fault first...

    Code:
    #include "writelb.h"
    
    int main (int argc, char* argv[]){
    
       FILE *fp,*fp2;
    
       /*checking the number of arguments*/
       if(argc != 3) {
          printf("Usage : %s <s.i. file> <binary file>\n", argv[0]);
          exit(0);
       } 
       /*opening the data file*/
       if((fp = fopen(argv[1],"r")) == NULL){
          fprintf(stderr, "File %s: open error\n", argv[1]);
          exit(1);
       }
       /*opening the binary file we writing to*/
       if((fp2 = fopen(argv[2],"wb")) == NULL){
          fprintf(stderr, "File %s: open error\n", argv[2]);
          exit(1);
       }
       char *lines, *guild, *blank;
       unsigned char *name, *chartemp;
       unsigned int race, classs, level;
       FixedLengthRecordPtr newRecord;
       FixedLengthPagePtr newPage;
       
       int i;
       blank = malloc (sizeof(char)*30);
       blank = "                              ";
       /*allocating memory*/
       if((lines = malloc(sizeof(char)*50))==NULL ||
       (name = malloc(sizeof(char)*12))==NULL ||
       (guild = malloc(sizeof(char)*30))==NULL ||
       (chartemp = malloc(sizeof(char)*50))==NULL ||
       (newPage = malloc(sizeof(FixedLengthPagePtr)))==NULL){
          fprintf(stderr,"insufficient memmory");
          exit(1);
       }
       
       for(i=0 ; i < 11 ; i++){
          printf("%d ",i);
          
          if((newPage->data[i] = malloc(sizeof(FixedLengthRecordPtr)))==NULL ){
             fprintf(stderr,"insufficient memmory");
             exit(1);
          }
          if((newPage->data[i]->name = malloc(sizeof(char)*12))==NULL ){
             fprintf(stderr,"insufficient memmory");
             exit(1);
          }
          if((newPage->data[i]->guild = malloc(sizeof(char)*30))==NULL ){
             fprintf(stderr,"insufficient memmory");
             exit(1);
          }
       }
       /*reading the lines from the data file "data_2008"*/
       int k = 0;
       
       while (fgets(lines,50,fp)!=NULL){
          printf("k is %d\n",k);
          
          /*getting rid of the new line char*/
          
          lines = strtok(lines,"\n");
          printf("line being tokenised - %s\n",lines);
          strcpy(newPage->data[k]->name, strtok(lines,","));
          printf("name - %s\n",newPage->data[k]->name);
          newPage->data[k]->race = atoi(strtok(NULL,","));
          printf("race - %d\n",newPage->data[k]->race );
          newPage->data[k]->classs = atoi(strtok(NULL,","));
          printf("class - %d\n",newPage->data[k]->classs );
          newPage->data[k]->level = atoi(strtok (NULL,","));
          printf("level - %d\n",newPage->data[k]->level );
          printf("checking guild \n");
          if((guild = strtok(NULL,"\0"))!=NULL){
             printf("guild is not NULL\n");
             strncpy(newPage->data[k]->guild, "test",30);
             printf("guild is not NULL after\n");
          }
          else{
             printf("guild is NULL\n");
             strcpy(newPage->data[k]->guild, blank);
             printf("guild is NULL after\n");
          }
          /*
          printf("%s,%d,%d,%d,%s\n",newPage->data[k]->name,newPage->data[k]->race,newPage->data[k]->classs,newPage->data[k]->level,newPage->data[k]->guild);
          */
          for (i = k; i>=0; i--){
             printf("here - %s\n",newPage->data[i]->guild);
          }
          /*k = 3 seg faults for no idea what reason*/
          k++;
          
          if (k==11){
             k=0;
             for (i = 0; i<11; i++){
                printf("here -%s",newPage->data[i]->name);
             }
          }
       }
       free(lines);
       free(name);
       free(guild);
       free(chartemp);
       
       free(newPage);
       
       fclose(fp);
       fclose(fp2);
    }
    the file included...
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/time.h>
    
    #define SUCCESS 1
    
    
    typedef struct record *FixedLengthRecordPtr;
    
    typedef struct record{
       unsigned char *name;
       unsigned int race;
       unsigned int classs;
       unsigned int level;
       unsigned char *guild;
    }Record;
    
    typedef struct page *FixedLengthPagePtr;
    
    typedef struct page{
       FixedLengthRecordPtr data[11];
    }Page;
    thank you for your time..

    - dougtheduck

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > blank = malloc (sizeof(char)*30);
    > blank = " ";
    Your 2nd assignment does several bad things.
    1. It leaks the memory you allocated with malloc.
    2. blank is now pointing to a string constant.
    3. If you try to modify the memory pointed to by blank, you'll get a segfault.
    4. If you try to free it, that too will be bad.

    Use
    Code:
    strcpy( blank, "    " );
    > lines = strtok(lines,"\n");
    Now you've trashed the pointer to your lines variable as well.
    So now you can neither use fgets() with it (reliably at least), and you certainly can't free it.

    Probably some other stuff, but you get the idea.
    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
    Noob of C
    Join Date
    Apr 2008
    Location
    Melbourne
    Posts
    10
    hmmm ok given i've changed those as you said
    Code:
       blank = malloc (sizeof(char)*30);
       strcpy(blank,"                              ");
    Code:
          chartemp = strtok(lines,"\n");
          printf("line being tokenised - &#37;s\n",lines);
          strcpy(newPage->data[k]->name, strtok(chartemp,","));
          printf("name - %s\n",newPage->data[k]->name);
          newPage->data[k]->race = atoi(strtok(NULL,","));
          printf("race - %d\n",newPage->data[k]->race );
          newPage->data[k]->classs = atoi(strtok(NULL,","));
          printf("class - %d\n",newPage->data[k]->classs );
          newPage->data[k]->level = atoi(strtok (NULL,","));
          printf("level - %d\n",newPage->data[k]->level );
          printf("checking guild \n");
          if((guild = strtok(NULL,"\0"))!=NULL){
             printf("guild is not NULL\n");
             strncpy(newPage->data[k]->guild, "test",30);
             printf("guild is not NULL after\n");
          }
          else{
             printf("guild is NULL\n");
             strcpy(newPage->data[k]->guild, blank);
             printf("guild is NULL after\n");
          }
    i'm more concerned about this part the last assignment... regarding the guild part... it gives me a seg fault when k reaches 3,

    and in gdb

    Code:
    Program received signal SIGSEGV, Segmentation fault.
    0xff2b218c in ?? ()
    i mean as in if i were to strcpy the guild part and the token happens to be a NULL then when i try to print guild it'll seg fault.. how do i check for that?
    Last edited by egoveneror2; 04-13-2008 at 12:04 PM.

  4. #4
    Noob of C
    Join Date
    Apr 2008
    Location
    Melbourne
    Posts
    10
    o the "test" part is hard coded atm... cause of testing purposes

  5. #5
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    What data do you have when k = 3? Is the guild empty? How far do you get when the segfault happens?

    Also, If you plan to use gdb, and you're using gcc as a compiler, you need to enable debugging symbols (so that you get something more exciting than line ?? in source file ""), by using the -g switch when you compile.

  6. #6
    Noob of C
    Join Date
    Apr 2008
    Location
    Melbourne
    Posts
    10
    k = 1 would be the token that has an empty guild
    however it doesnt seg fault with the code currently like that

    when i do a strcpy it seg faults at k = 1 cause of the NULL the strtok returns to the strcpy : -
    Code:
    strcpy(guild,strtok(NULL,"\0"));
    is there anyway i can handle the NULL that strtok returns? so i can still use something similar to this.

    a sample data file would be like this
    the full length is abt 1.5 million lines.
    Code:
    Ardt'hin,1,5,20,Fiery Legion
    Syxat-then,1,7,46,
    Caillitnys,3,2,18,The Forgivers
    Straszuenge,2,2,8,Online Fighters
    Morghaveru,5,8,20,Templars
    Ykeleardg,2,3,22,The Forgivers
    cheers

  7. #7
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    There isn't any way to handle a NULL pointer, other than checking for it and doing something else instead.

    I don't see anything about where your segfault occurs, other than k=3; I notice that 3 is longer than the rest, but that's the only thing I see.

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > typedef struct record *FixedLengthRecordPtr;
    Things like this are a waste of time, and needlessly obfuscate the code.

    IMO, it's far more important for you to have visibilty of the true number of levels of indirection at the point of use compared with any saving in having less typing (which in your case there isn't).
    The only time I habitually use a typedef on a pointer is for function pointers, and that's because the syntax is so damn hairy.

    > newPage = malloc(sizeof(FixedLengthPagePtr)
    You've allocated exactly the size of a pointer, not the size of the thing you're pointing at.
    Your other attempted allocations using these "typedef'ed pointers" are similarly short on the amount of memory they need to allocate.
    In short, buffer overruns abound.

    You can avoid all this by using this form.
    p = malloc ( sizeof *p * howManyOfThemYouWant );
    The compiler does all the work, and you no longer have to worry about whether you got the type name right, or the right number of *'s for indirection.


    Oh, and for good measure, your freeing code leaks memory as well.
    You need to free all your page->data[i] entries before freeing page.

    One final thing, if any of your strtok calls return NULL, then all those strcpy / atoi calls will blow up in your face as well.
    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.

  9. #9
    Noob of C
    Join Date
    Apr 2008
    Location
    Melbourne
    Posts
    10
    wow... thanx salem... fixed it...
    it was the memory allocation i did badly >_<

  10. #10
    Noob of C
    Join Date
    Apr 2008
    Location
    Melbourne
    Posts
    10
    another question same codes....

    Code:
    typedef struct record{
       char *name;
       unsigned int race;
       unsigned int classs;
       unsigned int level;
       char *guild;
    }Record;
    how come it seg faults when i change to

    Code:
    typedef struct record{
       char *name;
       char *guild;
       unsigned int race;
       unsigned int classs;
       unsigned int level;
    }Record;
    the .c file is the same as above with most of the fixes salem suggested

  11. #11
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    It means you're still doing something wrong.

    It also means you have an example of "works" != "bug free".

    Sometimes things work despite your attempts to make a mess of it. Other times, any tiny mistake is harshly dealt with by the OS.
    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.

  12. #12
    Noob of C
    Join Date
    Apr 2008
    Location
    Melbourne
    Posts
    10
    ok...

    haha.... i'm quite bad in C as you can see...

    hmmm... i'll try to look for my mess then...

  13. #13
    Noob of C
    Join Date
    Apr 2008
    Location
    Melbourne
    Posts
    10
    cool my mistake again i malloced a ptr instead of a record size.... >_<

    thanx again salem

  14. #14
    Day Dreamer
    Join Date
    Apr 2007
    Posts
    45
    Quote Originally Posted by egoveneror2 View Post
    another question same codes....

    Code:
    typedef struct record{
       char *name;
       unsigned int race;
       unsigned int classs;
       unsigned int level;
       char *guild;
    }Record;
    how come it seg faults when i change to

    Code:
    typedef struct record{
       char *name;
       char *guild;
       unsigned int race;
       unsigned int classs;
       unsigned int level;
    }Record;
    the .c file is the same as above with most of the fixes salem suggested
    Did you get a fix for that? I cant see a reason why that should happen!
    Initially looking at the datatype char I thought its the structure boundary thingy which says that a structure should end on an address which is divisible by 4 but then you the datatype was char * and not char!
    Moreover, the compiler takes care of that. So did you find an explanation to that?
    I would love to change the world but they dont give me the source code!

  15. #15
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    It's impossible to say directly what the problem is without seeing the code that uses the struct.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. unknown seg fault after malloc
    By seaking1 in forum C Programming
    Replies: 4
    Last Post: 02-25-2009, 07:51 PM
  2. Getting a seg fault
    By ammochck21 in forum C Programming
    Replies: 11
    Last Post: 01-23-2009, 05:27 AM
  3. seg fault
    By hka26 in forum C++ Programming
    Replies: 1
    Last Post: 10-08-2007, 01:38 AM
  4. Seg Fault Problem
    By ChazWest in forum C++ Programming
    Replies: 2
    Last Post: 04-18-2002, 03:24 PM
  5. seg fault on unix platform
    By Unregistered in forum C Programming
    Replies: 3
    Last Post: 12-08-2001, 12:04 PM