Tick tack
Tick tack

Reputation: 25

Segmentation fault when using pthreads

I'm having a segmentation fault while i'm doing a simulation of a metro station using threads The idea i'm going with is that i have 4 stations with 4 paths and 4 trains each train goes by a path to a certain station and the train moves by a thread my initial simulation was working just find until i try to enter a 4th thread ("Train") to my world where i start getting segmentation fault (core dumbed ) I got these as my structs :

struct Path {  
 int Direction; //if equals to 1 it's to the tunnel   0 it's away from the tunnel 
   int size;
   char name[25];  // A or B or C or D
   int Used;
};
 struct train {

   int TrainId;
   int   speed;
   int position;
   int direction;
   struct Path CurPath;

}; 

some paths initializers

 struct Path PathA; //Path A inital Info 
    PathA.Direction = 1 ;
    strcpy( PathA.name, "A");
    PathA.size = 20;
    paths[0]=PathA;

some train initializers as well :

   train1->speed = 20;
   train1->CurPath = PathA;
   train1->TrainId = 1;
   train1->direction = 1;
   train1->position = 0;
 pthread_create(&train1Th, NULL, run, (void *)train1);

and the run method for the thread :

void *run (void  *Train){
    //sleep(1);
    int i;
    struct train *Trains= (struct train*)Train;
    if((*Trains).TrainId == 1)
    i=0;
    if((*Trains).TrainId == 2)
    i=2;
    if((*Trains).TrainId == 3)
    i=0;
    if((*Trains).TrainId == 4)
    i=2;


    while(run){
    sleep(1);
    if((*Trains).TrainId == 1)
    if (i==8) i=0;
    if((*Trains).TrainId == 2)
    if (i==6) i=2;
    if((*Trains).TrainId == 3)
    if (i>8) i=0;
    if((*Trains).TrainId == 4)
    if (i>8) i=0;
    (*Trains).CurPath = paths[i];
    paths[i].Used = 0;
    if((*Trains).CurPath.Used == 1){ puts("Busy waiting");
    sleep(2);}

        printf("\nThe Train is on path : %s,is now at the endpoint with an id of %d", (*Trains).CurPath.name, (*Trains).TrainId);

    paths[i].Used == 1; 
    if((*Trains).TrainId == 1)
    i=i+4;
    if((*Trains).TrainId == 2)
    i=i+2;
    if((*Trains).TrainId == 3)
    i=i+7;
    if((*Trains).TrainId == 4)
    i=i+5;

    }

where the i is just for path choosing any ideas for what causing the segmentation fault when trying to add a new train ? Here's a copy of my code as whole :

    #include <stdio.h>
    #include <string.h>
    #include <pthread.h>
    #include <stdlib.h>
    #include <time.h>
    #include<sys/time.h>

    int semtime =20;
    struct Path {
       int Direction; //if equals to 1 it's to the tunnel   0 it's away from the tunnel 
       int size;
       char name[25];  // A or B or C or D
       int Used;
    };
    struct train {

       int TrainId;
       int   speed;
       int position;
       int direction;
       struct Path CurPath;

    }; 
     struct Path paths[8];
    void *run (void  *Train){
        //sleep(1);
        int i;
        struct train *Trains= (struct train*)Train;
        if((*Trains).TrainId == 1)
        i=0;
        if((*Trains).TrainId == 2)
        i=2;
        if((*Trains).TrainId == 3)
        i=0;
        if((*Trains).TrainId == 4)
        i=2;


        while(run){
        sleep(1);
        if((*Trains).TrainId == 1)
        if (i==8) i=0;
        if((*Trains).TrainId == 2)
        if (i==6) i=2;
        if((*Trains).TrainId == 3)
        if (i>8) i=0;
        if((*Trains).TrainId == 4)
        if (i>8) i=0;
        (*Trains).CurPath = paths[i];
        paths[i].Used = 0;
        if((*Trains).CurPath.Used == 1){ puts("Busy waiting");
        sleep(2);}

            printf("\nThe Train is on path : %s,is now at the endpoint with an id of %d", (*Trains).CurPath.name, (*Trains).TrainId);

        paths[i].Used == 1; 
        if((*Trains).TrainId == 1)
        i=i+4;
        if((*Trains).TrainId == 2)
        i=i+2;
        if((*Trains).TrainId == 3)
        i=i+7;
        if((*Trains).TrainId == 4)
        i=i+5;

        }
        //printf("%02d:%02d:%02d\n", tm->tm_hour, tm->tm_min, tm->tm_sec);

     /*   time_t now = time( NULL);

        struct tm now_tm = *localtime( &now);


        struct tm then_tm = now_tm;
        then_tm.tm_sec += semtime;   // add 50 seconds to the time

        mktime( &then_tm);      // normalize it

        printf( "%s\n", asctime( &now_tm));
        printf( "%s\n", asctime( &then_tm));
    */

            return NULL;

     }

    int main( ) {  
        /* Initilizing Paths */
       struct Path PathA; //Path A inital Info 
        PathA.Direction = 1 ;
        strcpy( PathA.name, "A");
        PathA.size = 20;
        paths[0]=PathA;

       struct Path PathA2; //Path A inital Info The other direction
        PathA.Direction = 0 ;
        strcpy( PathA.name, "A");
        PathA.size = 20;
        paths[1]=PathA2;

       struct Path PathB; //Path B inital Info
        malloc(sizeof(struct Path));
        PathB.Direction = 1 ;
        strcpy( PathB.name, "B");
        PathB.size = 20;
        paths[2]=PathB;

       struct Path PathB2; //Path A inital Info The other direction
        PathB2.Direction = 0 ;
        strcpy( PathB2.name, "B");
        PathB2.size = 20;
        paths[3]=PathB2;

       struct Path PathC; //Path c inital Info
        PathC.Direction = 1 ;
        strcpy( PathC.name, "C");
        PathC.size = 20;
        paths[4]=PathC;

       struct Path PathC2; //Path C inital Info The other direction
        PathC2.Direction = 0 ;
        strcpy( PathC2.name, "C");
        PathC2.size = 20;
        paths[5]=PathC2;

       struct Path PathD; //Path D inital Info
        PathD.Direction = 1 ;
        strcpy( PathD.name, "D");
        PathD.size = 20;
        paths[6]=PathD;

       struct Path PathD2; //Path D inital Info The other direction
        PathD2.Direction = 0 ;
        strcpy( PathD2.name, "D");
        PathD2.size = 20;
        paths[7]=PathD;

       struct train *train1;  
       pthread_t train1Th;

       train1->speed = 20;
       train1->CurPath = PathA;
       train1->TrainId = 1;
       train1->direction = 1;
       train1->position = 0;
     pthread_create(&train1Th, NULL, run, (void *)train1);


       struct train *train2;  
       pthread_t train2Th;

       train2->speed = 20;
       train2->CurPath = PathB;
       train2->TrainId = 2;
       train2->direction = 1;
       train2->position = 0;

     pthread_create(&train2Th, NULL, run, (void *)train2);

     struct train *train3;  
     pthread_t train3Th;


   train3->speed = 20;
   train3->CurPath = PathA;
   train3->TrainId = 3;
   train3->direction = 1;
   train3->position = 0;

 pthread_create(&train3Th, NULL, run, (void *)train3);


     struct train *train4;
        train4->TrainId = 4;


       return 0;
    }

the error is happening when i try to access TrainId

Upvotes: 1

Views: 1938

Answers (1)

CimCim
CimCim

Reputation: 48

As said in the comments, you try to affect a value to unallocated memory:

    struct train *train1;
    // you declare a pointer to a structure train, but your struct does not exists in memory

    train1->speed = 20;
    // and then, you initialize an unallocated memory with a value

The simpliest is probably to use train structure instead of pointer to structure (you will avoid problems of allocating and freeing memory) and gives the address of the structure when starting your thread:

    struct train train1;

    train1.speed = 20;
    [...]
    pthread_create(&train1Th, NULL, run, (void *)&train1);

Upvotes: 1

Related Questions