Thread: segmentation error during structured array (part of ip lookup)

  1. #1
    Registered User
    Join Date
    May 2012
    Location
    Tainan, Taiwan, Taiwan
    Posts
    10

    segmentation error during structured array (part of ip lookup)

    I have been facing with this problem for almost 5 days.
    This is part that grab IP address from file and store it as array.
    so hash tables are supposed to be like this:

    hashtable[length].which_element_of_table.IP_add

    Code:
    #include<stdlib.h>
    #include<stdio.h>
    #include<string.h>
    //*************
    struct ttyp
    {
        unsigned int index;
        struct prtyp{
            unsigned char len;
            unsigned char port;
            unsigned int ip;
            } *prefix;
    };
    
    int num_entry=0;
    struct ttyp *htable; 
    
    // READ IP FROM TEXT FILE
    void read_table(char *str,unsigned int *ip,int *len,unsigned int *nexthop)
    {
        char tok[]="./";
        char buf[100],*str1;
        unsigned int n[4];
        sprintf(buf,"%s\0",strtok(str,tok));
        n[0]=atoi(buf);
        sprintf(buf,"%s\0",strtok(NULL,tok));
        n[1]=atoi(buf);
        sprintf(buf,"%s\0",strtok(NULL,tok));
        n[2]=atoi(buf);
        sprintf(buf,"%s\0",strtok(NULL,tok));
        n[3]=atoi(buf);
        *nexthop=n[2];
        str1=(char *)strtok(NULL,tok);
        if(str1!=NULL)
        {
            sprintf(buf,"%s\0",str1);
            *len=atoi(buf);
        }
        else
        {
            if(n[1]==0&&n[2]==0&&n[3]==0)
                *len=8;
            else if(n[2]==0&&n[3]==0)
                *len=16;
            else if(n[3]==0)
                *len=24;
        }
        *ip=n[0];
        *ip<<=8;
        *ip+=n[1];
        *ip<<=8;
        *ip+=n[2];
        *ip<<=8;
        *ip+=n[3];
    }
    
    //BUILD HASH TABLE
    void hash_table(char *file_name)
    {
        int count,z;
        FILE *fp;
        int len;
        char string[100];
        unsigned int ip,nexthop;
        fp=fopen(file_name,"r");
    
        while(fgets(string,50,fp)!=NULL)
        {
            read_table(string,&ip,&len,&nexthop);
            num_entry++;
        }
        rewind(fp);
        //prefix=(struct prtyp *)malloc(num_entry*sizeof(struct prtyp));  // i think this line is unnecessary, so i comment it
        htable=(struct ttyp *)malloc(32*num_entry*sizeof(struct ttyp));
        for(count=1; count<=32; count++){
            htable[count].index=0;  //counter initialization
            }
        while(fgets(string,50,fp)!=NULL){
            read_table(string,&ip,&len,&nexthop);
    
            z=htable[len].index;
            htable[len].prefix[z].ip=ip;
            htable[len].prefix[z].port=nexthop;
            htable[len].index++;
            }
    }
    
    //MAIN
    
    int main(int argc,char *argv[])
    {
        hash_table(argv[1]);
        printf("\n=================================");
        printf("\nTotal prefix in txt file: %d", num_entry);
        printf("\n=================================\n");
        for(y=1;y<=32;y++){
            if(htable[y].index)
            printf("Table[%d] value numbers: %d\n",y,htable[y].index);
            }
    return0;
    }


    I thought i allocate enough memory htable pointer.

    But still get:
    Segmentation fault

    Anyone help ?


    Thanks,
    Kane

  2. #2
    Technical Lead QuantumPete's Avatar
    Join Date
    Aug 2007
    Location
    London, UK
    Posts
    894
    It depends on where you get the segmentation fault. Can you post the stack trace, please?
    "No-one else has reported this problem, you're either crazy or a liar" - Dogbert Technical Support
    "Have you tried turning it off and on again?" - The IT Crowd

  3. #3
    Registered User claudiu's Avatar
    Join Date
    Feb 2010
    Location
    London, United Kingdom
    Posts
    2,094
    You are only allocating memory for your ttyp, never for the prefix inside. You are then attempting to write at the garbage memory it points to.
    1. Get rid of gets(). Never ever ever use it again. Replace it with fgets() and use that instead.
    2. Get rid of void main and replace it with int main(void) and return 0 at the end of the function.
    3. Get rid of conio.h and other antiquated DOS crap headers.
    4. Don't cast the return value of malloc, even if you always always always make sure that stdlib.h is included.

  4. #4
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    Also all your for loops are wrong. Valid array indexes are 0 .. number of elements - 1 in C.
    Kurt

  5. #5
    Registered User
    Join Date
    May 2012
    Location
    Tainan, Taiwan, Taiwan
    Posts
    10

    reply

    root@kane-BM5220-BM5320-BM5620:/home/kane/my_files/course_files/midterm_project# gcc 8_May.c -o test2
    root@kane-BM5220-BM5320-BM5620:/home/kane/my_files/course_files/midterm_project# ./test1 traffic.txt table.txt
    Segmentation fault

  6. #6
    Technical Lead QuantumPete's Avatar
    Join Date
    Aug 2007
    Location
    London, UK
    Posts
    894
    Quote Originally Posted by eegii_evol View Post
    root@kane-BM5220-BM5320-BM5620:/home/kane/my_files/course_files/midterm_project# gcc 8_May.c -o test2
    root@kane-BM5220-BM5320-BM5620:/home/kane/my_files/course_files/midterm_project# ./test1 traffic.txt table.txt
    Segmentation fault
    reply
    "No-one else has reported this problem, you're either crazy or a liar" - Dogbert Technical Support
    "Have you tried turning it off and on again?" - The IT Crowd

  7. #7
    Registered User
    Join Date
    May 2012
    Location
    Tainan, Taiwan, Taiwan
    Posts
    10
    Zuk: I knew array starts from 0. But i tried to represent array number as length directly. that was my mistake thanks Kurt. Let me try now.

    Claudiu: In this case how should I declare structures.
    Actually I did this individually, but still got error. Like this:

    Code:
    struct ttyp
    {
        unsigned int index;
        struct prtyp *prefix;
    };
    
    struct prtyp{
        unsigned char len;
        unsigned char port;
        unsigned int ip;
    };
    struct prtyp *prefix;
    struct ttyp *htable;
    prefix=(struct prtyp *)malloc(num_entry*sizeof(struct prtyp));
    htable=(struct ttyp *)malloc(32*sizeof(struct ttyp));


  8. #8
    Registered User ledow's Avatar
    Join Date
    Dec 2011
    Posts
    435
    1) That's not a stack trace.
    2) You need to get yourself a proper debugger, not just run the program.
    3) You need to compile with warnings on:

    gcc -O3 -g3 -Wall -c -fmessage-length=0 -otest.o ..\test.c
    ..\test.c: In function 'read_table':
    ..\test.c:24: warning: embedded '\0' in format
    ..\test.c:26: warning: embedded '\0' in format
    ..\test.c:28: warning: embedded '\0' in format
    ..\test.c:30: warning: embedded '\0' in format
    ..\test.c:36: warning: embedded '\0' in format
    ..\test.c: In function 'main':
    ..\test.c:96: error: 'y' undeclared (first use in this function)
    ..\test.c:96: error: (Each undeclared identifier is reported only once
    ..\test.c:96: error: for each function it appears in.)
    ..\test.c:100: error: 'return0' undeclared (first use in this function)
    Build error occurred, build is stopped
    Time consumed: 4535 ms.

    The last one might just be because your formatting appears screwed on the code drop you did. But before I even TRY to run the program, I've got those errors. And my debugger breakpoints right at the point where something goes wrong with one click.

    Try actually WORKING OUT WHAT'S WRONG. Even assuming that you don't have a proper debugger, stick a printf that you can spot into the functions so you at least know if it crashes before a certain line or after it. It would take two minutes to do that on EVERY line of code, run it, and work out what line it crashes on yourself. From there, it's a short step to work out WHY that line crashed and what caused that to happen (e.g. overflow, etc.) and how to fix it.

    But just running a program with ZERO WARNINGS ENABLED and then expecting it to magically tell you what's wrong is like trying to diagnose a car engine fault by getting on the motorway and telling the recovery vehicle "It just stopped" (not how, when, what you did, were, what the gauges read at the time, what noises it made, etc.)

    - Compiler warnings are like "Bridge Out Ahead" warnings. DON'T just ignore them.
    - A compiler error is something SO stupid that the compiler genuinely can't carry on with its job. A compiler warning is the compiler saying "Well, that's bloody stupid but if you WANT to ignore me..." and carrying on.
    - The best debugging tool in the world is a bunch of printf()'s for everything important around the bits you think might be wrong.

  9. #9
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    Guess that is what you want
    Code:
    struct ttyp
    {
        unsigned int index;
        struct prtyp *prefix;
    };
     
    struct prtyp{
        unsigned char len;
        unsigned char port;
        unsigned int ip;
    };
    
    struct ttyp *htable;
    
    htable=malloc(32*sizeof(struct ttyp));
    htable->prefix=malloc(num_entry*sizeof(struct prtyp));
    Kurt

  10. #10
    Registered User
    Join Date
    May 2012
    Location
    Tainan, Taiwan, Taiwan
    Posts
    10

    reply

    I have changed code some parts by fixing arrays and separating structures.
    Code:
    #include<stdlib.h>
    #include<stdio.h>
    #include<string.h>
    struct ttyp
    {
        unsigned int index;
        struct prtyp *prefix;
    };
    
    struct prtyp{
        unsigned char len;
        unsigned char port;
        unsigned int ip;
    } ;
    
    struct prtyp *prefix;
    struct ttyp *htable;
    int num_entry=0;
    
    ////////////////////////////////////////////////////////////////////////////////////
    void read_table(char *str,unsigned int *ip,int *len,unsigned int *nexthop)
    {
        char tok[]="./";
        char buf[100],*str1;
        unsigned int n[4];
        sprintf(buf,"%s\0",strtok(str,tok));
        n[0]=atoi(buf);
        sprintf(buf,"%s\0",strtok(NULL,tok));
        n[1]=atoi(buf);
        sprintf(buf,"%s\0",strtok(NULL,tok));
        n[2]=atoi(buf);
        sprintf(buf,"%s\0",strtok(NULL,tok));
        n[3]=atoi(buf);
        *nexthop=n[2];
        str1=(char *)strtok(NULL,tok);
        if(str1!=NULL)
        {
            sprintf(buf,"%s\0",str1);
            *len=atoi(buf);
        }
        else
        {
            if(n[1]==0&&n[2]==0&&n[3]==0)
                *len=8;
            else if(n[2]==0&&n[3]==0)
                *len=16;
            else if(n[3]==0)
                *len=24;
        }
        *ip=n[0];
        *ip<<=8;
        *ip+=n[1];
        *ip<<=8;
        *ip+=n[2];
        *ip<<=8;
        *ip+=n[3];
    }
    
    //********************************************************
    void hash_table(char *file_name)
    {
        int count,z;
        FILE *fp;
        int len;
        char string[100];
        unsigned int ip,nexthop;
        fp=fopen(file_name,"r");
    
        while(fgets(string,50,fp)!=NULL)
        {
            read_table(string,&ip,&len,&nexthop);
            num_entry++;
        }
        rewind(fp);
        prefix=(struct prtyp *)malloc(num_entry*sizeof(struct prtyp));
        htable=(struct ttyp *)malloc(32*sizeof(struct ttyp));
        for(count=0; count<=31; count++){
            htable[count].index=0;  //counter initialization
            }
        while(fgets(string,50,fp)!=NULL){
            read_table(string,&ip,&len,&nexthop);
    
            z=htable[len-1].index;
            htable[len-1].prefix[z].ip=ip;
            htable[len-1].index++;
            }
    }
    
    //*********************************************************
    int main(int argc,char *argv[])
    {
        if(argc!=3)
        {
            printf("Please execute the file as the following way:\n");
            printf("%s  routing_table_file_name  query_table_file_name\n",argv[0]);
            exit(1);
        }
        //set_query(argv[2]);
        int y;
    
    
        hash_table(argv[1]);
        printf("\n=================================");
        printf("\nTotal prefix in txt file: %d", num_entry);
        printf("\n=================================\n");
        for(y=0;y<=31;y++){
            if(htable[y].index)
            printf("Table[%d] value numbers: %d\n",y+1,htable[y].index);
            }
        printf("TEST: %d",htable[23].prefix[0].ip); //there is 23 length exists in file
    
        return 0;
    
    }


    TRACE:

    root@kane-BM5220-BM5320-BM5620:/home/kane/my_files/course_files/midterm_project# gcc -O3 -g3 -Wall -c -fmessage-length=0 -otest.o trash.c
    trash.c: In function ‘read_table’:
    trash.c:26:5: warning: embedded ‘\0’ in format [-Wformat-contains-nul]
    trash.c:28:5: warning: embedded ‘\0’ in format [-Wformat-contains-nul]
    trash.c:30:5: warning: embedded ‘\0’ in format [-Wformat-contains-nul]
    trash.c:32:5: warning: embedded ‘\0’ in format [-Wformat-contains-nul]
    trash.c:38:9: warning: embedded ‘\0’ in format [-Wformat-contains-nul]



    Thanks,
    Kane

  11. #11
    Registered User
    Join Date
    May 2012
    Location
    Tainan, Taiwan, Taiwan
    Posts
    10
    Zuk,

    Ohh thanks man, I gotta try it now.
    Last edited by eegii_evol; 05-10-2012 at 05:43 AM.

  12. #12
    Registered User
    Join Date
    May 2012
    Location
    Tainan, Taiwan, Taiwan
    Posts
    10
    Quote Originally Posted by ledow View Post
    1) That's not a stack trace.
    2) You need to get yourself a proper debugger, not just run the program.
    3) You need to compile with warnings on:

    gcc -O3 -g3 -Wall -c -fmessage-length=0 -otest.o ..\test.c
    ..\test.c: In function 'read_table':
    ..\test.c:24: warning: embedded '\0' in format
    ..\test.c:26: warning: embedded '\0' in format
    ..\test.c:28: warning: embedded '\0' in format
    ..\test.c:30: warning: embedded '\0' in format
    ..\test.c:36: warning: embedded '\0' in format
    ..\test.c: In function 'main':
    ..\test.c:96: error: 'y' undeclared (first use in this function)
    ..\test.c:96: error: (Each undeclared identifier is reported only once
    ..\test.c:96: error: for each function it appears in.)
    ..\test.c:100: error: 'return0' undeclared (first use in this function)
    Build error occurred, build is stopped
    Time consumed: 4535 ms.

    The last one might just be because your formatting appears screwed on the code drop you did. But before I even TRY to run the program, I've got those errors. And my debugger breakpoints right at the point where something goes wrong with one click.

    Try actually WORKING OUT WHAT'S WRONG. Even assuming that you don't have a proper debugger, stick a printf that you can spot into the functions so you at least know if it crashes before a certain line or after it. It would take two minutes to do that on EVERY line of code, run it, and work out what line it crashes on yourself. From there, it's a short step to work out WHY that line crashed and what caused that to happen (e.g. overflow, etc.) and how to fix it.

    But just running a program with ZERO WARNINGS ENABLED and then expecting it to magically tell you what's wrong is like trying to diagnose a car engine fault by getting on the motorway and telling the recovery vehicle "It just stopped" (not how, when, what you did, were, what the gauges read at the time, what noises it made, etc.)
    I really appreciate for your suggestion and help. Thank you for your time. I will do my best on it.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. A weird segmentation fault error with 2D array
    By uwowizard in forum C Programming
    Replies: 4
    Last Post: 12-18-2011, 08:06 PM
  2. Minimizing array lookup times using effective indexing...?
    By The Dog in forum Game Programming
    Replies: 5
    Last Post: 02-08-2011, 07:11 AM
  3. sorting structured array problem
    By matrix0978 in forum C Programming
    Replies: 7
    Last Post: 11-12-2009, 01:42 AM
  4. qsort( ) on a structured array
    By Thumper333 in forum C Programming
    Replies: 2
    Last Post: 10-21-2004, 07:39 PM