Segmentation fault przy użyciu pthread_create

0

Witam,

Przy próbie tworzenia takiej małej tekstowej symulacji skrzyżowania wyskakuje mi błąd "segmentation fault", którego źródło podejrzewam czai się w funkcji drive_car() lub też przy tworzeniu wielu wątków w put_cars(). A moje pytanie jest oczywiste - gdzie robię błąd? Oczywiście program jest nieskończony, funkcja drive_car() ma w tym momencie po prostu dowolnie przesuwać pozycję "aut" o 7 pozycji.

To jest mój pierwszy program z użyciem pthread_create, stąd proszę o wyrozumiałość w razie ewentualnych szkolnych błędów. W razie gdyby się okazało, że generalnie źle podchodzę do sprawy, prosiłbym o ewentualne porady gdzie szukać konkretnej wiedzy w tym temacie, z góry dziękuję.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>

typedef struct car
{
 int from_where; // 0 - gora, 1 - prawo, 2 - dol, 3 - lewo
 int direction; // 0 - lewo, 1 - prawo, 2 - prosto

 int x;
 int y;
} car;

struct car t_cars[50];
pthread_t ID[50];
int GO=0;

char t_crossroad[21][21] = {
  { '#','#','#','#','#','#','#',' ',' ',' ','|',' ',' ',' ','#','#','#','#','#','#','#' },
  { '#','#','#','#','#','#','#',' ',' ',' ','|',' ',' ',' ','#','#','#','#','#','#','#' },
  { '#','#','#','#','#','#','#',' ',' ',' ','|',' ',' ',' ','#','#','#','#','#','#','#' },
  { '#','#','#','#','#','#','#',' ',' ',' ','|',' ',' ',' ','#','#','#','#','#','#','#' },
  { '#','#','#','#','#','#','#',' ',' ',' ','|',' ',' ',' ','#','#','#','#','#','#','#' },
  { '#','#','#','#','#','#','#',' ',' ',' ','|',' ',' ',' ','#','#','#','#','#','#','#' },
  { '#','#','#','#','#','#','#',' ',' ',' ','|',' ',' ',' ','#','#','#','#','#','#','#' },
  { ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ' },
  { ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ' },
  { ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ' },
  { '-','-','-','-','-','-','-',' ',' ',' ',' ',' ',' ',' ','-','-','-','-','-','-','-' },
  { ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ' },
  { ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ' },
  { ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ' },
  { '#','#','#','#','#','#','#',' ',' ',' ','|',' ',' ',' ','#','#','#','#','#','#','#' },
  { '#','#','#','#','#','#','#',' ',' ',' ','|',' ',' ',' ','#','#','#','#','#','#','#' },
  { '#','#','#','#','#','#','#',' ',' ',' ','|',' ',' ',' ','#','#','#','#','#','#','#' },
  { '#','#','#','#','#','#','#',' ',' ',' ','|',' ',' ',' ','#','#','#','#','#','#','#' },
  { '#','#','#','#','#','#','#',' ',' ',' ','|',' ',' ',' ','#','#','#','#','#','#','#' },
  { '#','#','#','#','#','#','#',' ',' ',' ','|',' ',' ',' ','#','#','#','#','#','#','#' },
  { '#','#','#','#','#','#','#',' ',' ',' ','|',' ',' ',' ','#','#','#','#','#','#','#' },
};


void* print_crossroad (void* unused)
{
 int i;
 int j;

 while(1)
 {
  for (i=0; i<21; i++)
  {
   for (j=0; j<21; j++)
    printf(" %c ",t_crossroad[i][j]);
   printf("\n");
  }
  sleep(1);
  system("clear");
 }
}

void clear_t_car ()
{
 int i;
 for(i=0;i<30;i++)
 {
  t_cars[i].from_where = 0;
  t_cars[i].direction = 0;
  t_cars[i].x = 0;
  t_cars[i].y = 0;
 }
}

void* drive_car (void *t)
{
 int i;
 struct car *s_car = (struct car*)t;

 for(i=0;i<7;i++)
  {
   s_car->x = s_car->x - 1;
   t_crossroad[s_car->x][s_car->y] = s_car->from_where;
   t_crossroad[s_car->x+1][s_car->y] = ' ';
   sleep(1);
  }

}

void* put_cars (void* unused)
{
 int i=0;
 int set_direction;
 int set_from_where;
 while(1)
 {
  srand(time(0));
  set_from_where = rand() % 4;
  set_direction = rand() % 3;
  sleep(3);
  switch (set_from_where)
  {
   case 0:
    if (t_crossroad[0][8] == ' ')
    {
     t_cars[i].from_where = '0';
     t_cars[i].direction = set_direction;
     t_cars[i].x = 0;
     t_cars[i].y = 8;
     pthread_create(&ID[i], NULL, &drive_car, (void*) &t_cars[i]);
     i++;
    }
   break;

   case 1:
    if (t_crossroad[8][20] == ' ')
    {
     t_cars[i].from_where = '1';
     t_cars[i].direction = set_direction;
     t_cars[i].x = 8;
     t_cars[i].y = 20;
     pthread_create(&ID[i], NULL, &drive_car, (void*) &t_cars[i]);
     i++;
    }
   break;

   case 2:
    if (t_crossroad[12][0] == ' ')
    {
     t_cars[i].from_where = '3';
     t_cars[i].direction = set_direction;
     t_cars[i].x = 12;
     t_cars[i].y = 0;
     pthread_create(&ID[i], NULL, &drive_car, (void*) &t_cars[i]);
     i++;
    }
   break;

   case 3:
    if (t_crossroad[20][12] == ' ')
    {
     t_cars[i].from_where = '2';
     t_cars[i].direction = set_direction;
     t_cars[i].x = 20;
     t_cars[i].y = 12;
     pthread_create(&ID[i], NULL, &drive_car, (void*) &t_cars[i]);
     i++;
    }
   break;

   default:
   printf("Błąd w put_the_cars!");
   break;
  }
 }
}

int main ()
{
 clear_t_car();

 pthread_t IDA,IDB;
 pthread_create(&IDA, NULL, &print_crossroad, NULL);
 pthread_create(&IDB, NULL, &put_cars, NULL);

 while (1);
 return 0;
} 
0

Segmentation Fault zawsze (chyba) oznacza to, że masz wskaźnik pokazujący na nieutworzony obiekt (albo utworzony ale już zniszczony - pamięć zwolniona, a Ty dalej próbujesz coś tam robić) i go używasz albo próbujesz odwołać się poza zakres tablicy (co de facto jest tym samym, co pierwszy przypadek ;p).

0

Nie wnikałem jakoś szczególnie w kod, ale nie widzę ograniczenia nałożonego na dodawanie nowych samochodów. Podejrzewam, że indeks i wewnątrz put_cars wykracza znacznie poza zakres tablicy.

while(1)
{
        srand(time(0));

        (...)

Wywal srand poza pętle.

 while (1);

Użyj pthread_join.

0

Dzięki za pomoc, problem polegał na odwoływaniu się poza zakres tablicy. A sam program już działa, z drobnymi uchybieniami do poprawki. Jeszcze raz dzięki!

P.s.

Mam do zrealizowania w ramach projektu na studiach dowolną aplikację pokazującą zarządzanie procesami i wątkami, komunikację między wątkami. Projekt ma korzystać z CreateProcess z Winapi. Moglibyście mi coś polecić, tzn. podsunąć pomysł na jakąś prostą aplikację, która by to realizowała? Oczywiście temat rzeka i pomysłów tutaj może być wiele, bo aplikacja może być dowolna, "cokolwiek" wymyślę pewnie sam, ale wolałbym już na starcie wiedzieć, że to co robię jest w miarę nieskomplikowane, czytelne i przydatne. A przypuszczam, że osobom z doświadczeniem w tej dziedzinie zapewne łatwiej będzie mi coś w tym stylu podsunąć, samemu mogę nieświadomie wkopać się w coś, co z pozoru wydaje się proste, a w praktyce będzie młyn. Z góry dzięki za pomoc.

1 użytkowników online, w tym zalogowanych: 0, gości: 1