Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 13
  1. #1

    [C] Thread - segmentation fault e floating point exception

    Ciao a tutti! Io e la mia collega abbiamo bisogno del vostro aiuto!
    Dobbiamo fare una versione (molto semplificata) di Space Invaders e usare i thread per la comunicazione tra i processi..Il problema è che durante l'esecuzione, il programma si blocca o a causa della segmentation fault o perchè viene sollevata la floating point exception..Il motivo??boooh!!!Vi posto il codice..è un po' lunghetto, ma ci sono tanti commenti così potete capire cosa abbiamo fatto..Vi prego..aiutateci!!
    codice:
    #include <stdio.h>
    #include <time.h>
    #include <curses.h>
    #include <pthread.h>
    #include <stdlib.h>
    #include <signal.h>
    #include <semaphore.h>
    #include <unistd.h>
    
    #define PASSO 1 //entita' dello spostamento del nemico
    #define SINISTRA 68 // freccia sx
    #define DESTRA 67 // freccia dx
    #define SGANCIA 32 // spazio
    #define MAXX 80 // numero di colonne dello schermo
    #define MAXY 24 // numero di righe dello schermo
    #define M 2 // numero di nemici di 1° livello
    #define G 4 // numero di nemici di 2° livello per gruppo
    #define BUFFER_DIM 100000
    
    
    //** Prototipi funzioni **//
    void * astronave_func(void * arg);
    void * missile_func(void * arg);
    void * nemico_func(void * arg);
    void * nemico2_func(void * arg);
    void * bomba_func(void * arg);
    void * controllo_func(void * arg);
    
    
    //**Struttura per la comunicazione fra figli e padre**//
    typedef struct pos
         {
            char c; // soggetto che invia il dato: astronave, nemico, bomba o missile
            int x; // coordinata x
            int y; // coordinata y
            int DIRX; // direzione del nemico di 2° livello
            int p; // posizione del nemico all'interno del vettore v[] che rappresenta il gruppo di nemici di primo livello
            int pid; // pid del processo
            int vita; // 0: il nemico è morto; 1: il nemico è vivo
    	int xi; // coordinata x del primo nemico di secondo livello
            int xf; // coordinata x dell'ultimo nemico di secondo livello
            int nem_vivi[G]; // vettore che indica lo stato di vita dei nemici di secondo livello all'interno di ciascun gruppo
            int g; // rappresenta il numero del gruppo a cui appartiene il nemico di secondo livello
            int n; // rappresenta il numero assegnato al nemico di 2° livello all'interno del proprio gruppo
          } pos;
    
    
    typedef struct argomenti // struttura per passare più argomenti ad una funzione thread
         {
    	int x; // posizione in x (dell'astronave o del nemico)
    	int y; // posizione in y (dell'astronave o del nemico)
    	int i; // indice i
         } args;
    
    
    //** Inizializzazioni buffer e semafori **//
    pos buffer[BUFFER_DIM]; // buffer condiviso
    int IN = 0; // variabile che indica le posizioni occupate nel buffer
    int OUT = 0; // variabile che indica le posizioni disponibili nel buffer
    sem_t presenti, disponibili; // variabili che indicano il valore del semaforo, ovvero la presenza o meno di job disponibili
    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // mutex per evitare la race condiction
    
    
    main()
    {
    initscr();      // inizializzazione dello schermo
    start_color(); // per l'utilizzazione dei colori
    noecho();     // i caretteri corrispondenti ai tasti premuti non saranno visualizzati sullo schermo del terminale
    curs_set(0); // nasconde il cursone
    
    
    sem_init(&disponibili, 0, BUFFER_DIM); // inizializzazione semaforo disponibili
    sem_init(&presenti, 0, 0); // inizializzazione semaforo presenti
    //pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // inizializzazione mutex
    
    srand(time(NULL));
    
    pthread_t astronave_id, nemico_id[M], controllo_id;
    int i;
    
    //creazione dei thread
    pthread_create(&astronave_id, NULL, &astronave_func, NULL);
    for(i=0;i<M;i++)
         pthread_create(&nemico_id[i], NULL, &nemico_func, &i);
    
    //evita che vengano deallocati dati indispensabili ai thread alla terminazione del main
    //pthread_join(astronave_id, NULL);
    
    pthread_create(&controllo_id, NULL, &controllo_func, NULL);
    pthread_join(controllo_id, NULL);
    
    /** Siamo usciti dal controllo e si terminano i procssi figli. Ripristina il normale modo operativo dello schermo **/
    endwin();
    
    return(0);
    }
    
    /** Funzione ASTRONAVE **/
    void * astronave_func(void * arg)
    {
    pos pos_astronave;
    args pos;
    pthread_t missile_id[2]; // l'astronave spara contemporaneamente due missili:uno a destra e uno a sinistra
    int i;
    
    pos_astronave.c='#';
    pos_astronave.x=MAXX/2;
    pos_astronave.y=MAXY-1;
    pos_astronave.pid=pthread_self();
    
    sem_wait(&disponibili);
    pthread_mutex_lock(&mutex);
    buffer[IN] = pos_astronave;
    IN=(IN+1)%BUFFER_DIM;
    sem_post(&presenti); // incrementa il semaforo
    pthread_mutex_unlock(&mutex);
    
    while(1)
         {
          char c;
          switch(c=getch()) { //gestione movimento o sgancio dei missili da parte dell'astronave
            case SINISTRA: if(pos_astronave.x>0){
                                          pos_astronave.x-=1; 				      
    					     } // fine if(pos_astronave.x>0)
                                       break;
            case DESTRA: if(pos_astronave.x<MAXX-1){
                                        pos_astronave.x+=1;
    						 }
                                     break;
            case SGANCIA: for(i=0;i<2;i++){
    					pos.i=i;
    					pos.x=pos_astronave.x;
    					pos.y=pos_astronave.y;
    				    	pthread_create(&missile_id[i], NULL, &missile_func, &pos); 
    					//pthread_join(missile_id[i], NULL); 
    				      }
                                      break;
                                    } // fine switch gestione movimento
    
    	sem_wait(&disponibili);
    	pthread_mutex_lock(&mutex);
    	buffer[IN] = pos_astronave;
    	IN=(IN+1)%BUFFER_DIM;
    	sem_post(&presenti); // incrementa il semaforo
    	pthread_mutex_unlock(&mutex);
    
        } // fine while
    } // fine Funzione Astronave
    
    
    /** Funzione MISSILE **/
    void * missile_func(void * arg)
    {
        pos pos_missile;
        args * pos = (args *)arg;
        int i = pos->i;
    
        pos_missile.c='*';                /*Effettuo il primo assegnamento*/
        pos_missile.pid=pthread_self();
        pos_missile.p=i;   // può essere 0 o 1 e indica quella che sarÃ_ la direzione del missile (dx o sx)
    
        if(i%2) // se i è dispari
           pos_missile.x=pos->x +PASSO; // vÃ_ a sinistra
        else // altrimenti
           pos_missile.x=pos->x -PASSO; // vÃ_ a destra
     
         pos_missile.y=pos->y-1;
    
        sem_wait(&disponibili);
        pthread_mutex_lock(&mutex);
        buffer[IN] = pos_missile;
        IN=(IN+1)%BUFFER_DIM;
        sem_post(&presenti); // incrementa il semaforo
        pthread_mutex_unlock(&mutex);
    
    
    
        if(i%2)   //se i=1 il missile vÃ_ a sinistra altrimenti a destra
          while(1)
                  {
                    pos_missile.x+=PASSO;
                    pos_missile.y-=PASSO;
                 
    		sem_wait(&disponibili);
                    pthread_mutex_lock(&mutex);
    		buffer[IN] = pos_missile;
    		IN=(IN+1)%BUFFER_DIM;
    		sem_post(&presenti); // incrementa il semaforo
        		pthread_mutex_unlock(&mutex);
    
                    usleep(200000);
                  }
        else
          while(1)
                  {
                    pos_missile.x-=PASSO;
                    pos_missile.y-=PASSO;
                    
    		sem_wait(&disponibili);
                    pthread_mutex_lock(&mutex);
                    buffer[IN] = pos_missile;
    		IN=(IN+1)%BUFFER_DIM;
    		sem_post(&presenti); // incrementa il semaforo
        		pthread_mutex_unlock(&mutex);
    
                    usleep(200000);
                  }
    
    } // fine Funzione Missile
    
    
    /** Funzione BOMBA **/
    void * bomba_func(void * arg)
    {
       pos pos_bomba;
       args * pos = (args *)arg;
     
       pos_bomba.c='o';   //inizializzo: la bomba parte dalla stessa colonna del nemico una posizione in avanti
       pos_bomba.x=pos->x;
       pos_bomba.y=pos->y +PASSO;
       pos_bomba.pid=pthread_self();
    
       sem_wait(&disponibili);
       pthread_mutex_lock(&mutex);
       buffer[IN] = pos_bomba;
       IN=(IN+1)%BUFFER_DIM;
       sem_post(&presenti); // incrementa il semaforo
       pthread_mutex_unlock(&mutex);
       
          while(1)
            {
                  pos_bomba.y+=PASSO;
    
    	      sem_wait(&disponibili);
                  pthread_mutex_lock(&mutex);
    	      buffer[IN] = pos_bomba;
    	      IN=(IN+1)%BUFFER_DIM;
    	      sem_post(&presenti); // incrementa il semaforo
        	      pthread_mutex_unlock(&mutex);
                  usleep(300000);
             }
    
    }//fine funzione bomba
    
    
    /** Funzione NEMICO **/
    void * nemico_func(void * arg)
    {
    pos pos_nemico;
    int i = *((int *)arg);
    int dx,dy; // spostamenti in x e y;
    int SOGLIAX; // soglia oltre la quale il nemico non può andare - può essere 1 o MAXX-1
    int DIRX; // direzione in x - se dirx=1 vÃ_ a destra, se dirx=-1 va a sinistra
    int time_giu=0; // contatore per far scendere il nemico
    int SOGLIA_GIU=10*(0+rand()%4)+i*5; // soglia per far scendere il nemico di una riga
    int time_bomb=1; // contatore per far sganciare una bomba
    int SOGLIA_BOMB=30+i*(0+rand()%5); // soglia per far sganciare la bomba
    args pos;
    pthread_t bomba_id;
    
    pos_nemico.c='$';
    pos_nemico.p=i;
    pos_nemico.pid=pthread_self();
    pos_nemico.y=1; // i nemici partono tutti sulla stessa riga
    pos_nemico.x=9+(i*20); // ma distanziati
    
    if(!(i%2)) // se il numero assegnato al nemico è pari
      {
        DIRX=1; // vÃ_ a destra
        SOGLIAX=MAXX-1; // e la soglia max in x è MAXX-1
      }
    else // altrimenti
       {
         DIRX=-1; // vÃ_ a sinistra
         SOGLIAX=1; // e la soglia max in x è 1
       }
    
    sem_wait(&disponibili);
    pthread_mutex_lock(&mutex);
    buffer[IN] = pos_nemico;
    IN=(IN+1)%BUFFER_DIM;
    sem_post(&presenti); // incrementa il semaforo
    pthread_mutex_unlock(&mutex);
    
    while(1)
    {
     
          if(pos_nemico.x==SOGLIAX) // se il nemico sbatte contro una parete laterale
           {
             DIRX*=-1; // cambio la direzione
             if(SOGLIAX==MAXX-1) // se la nuova direzione è destra
                SOGLIAX=1; // la soglia è MAXX-1
             else // altrimenti
                SOGLIAX=MAXX-1; // la soglia è 1
           }   
    
         if(DIRX==1) // se la direzione è destra
          dx=PASSO; // il suo spostamento sarÃ_ di PASSO
        else // altrimenti
          dx=-PASSO; // il suo spostamento sarÃ_ di -PASSO
          
        pos_nemico.x+=dx; // scriviamo la posizione in x del nemico
    
        if(!(time_giu%SOGLIA_GIU)) // ad intervalli regolari
           {
             dy=PASSO; // il nemico avanza di PASSO verso la soglia massima in Y
             time_giu=1; // riazzero il contatore
           }
        else
           {
             dy=0; // il nemico non avanza verso la soglia massima in Y
             time_giu++; // aggiorno il contatore per la discesa del nemico
           }
    
        pos_nemico.y+=dy; // scriviamo la posizione in y del nemico
    
        sem_wait(&disponibili);
        pthread_mutex_lock(&mutex);
        buffer[IN] = pos_nemico;
        IN=(IN+1)%BUFFER_DIM;
        sem_post(&presenti); // incrementa il semaforo
        pthread_mutex_unlock(&mutex);
    
    
        if(!(time_bomb%SOGLIA_BOMB)){ // ad intervalli regolari
    	pos.x = pos_nemico.x;
    	pos.y = pos_nemico.y;
            pthread_create(&bomba_id, NULL, &bomba_func, &pos); 
    	//pthread_join(bomba_id, NULL);
                                    }
        time_bomb++; // aggiorno il contatore per la bomba
    
        usleep(300000);
    
    } // fine while;
    
    } // fine Funzione Nemico
    (continua...)
    Mau

  2. #2
    (...continuo)

    codice:
    /** Funzione NEMICO2 **/
    void * nemico2_func(void * arg)
    {
    pos pos_nemico2;
    args *p = (args *)arg;
    args pos;
    int i = p->i;
    int x = p->x;
    int y = p->y;
    int j;
    int dx,dy;
    int SOGLIAX;
    int SOGLIA_GIU=10*(0+rand()%4)+i*5; // soglia per far scendere il nemico di una riga
    int time_giu=0;
    int time_bomb=1;
    int SOGLIA_BOMB=30+i*(0+rand()%5); // soglia per far sganciare la bomba
    pthread_t bomba_id;
    
    pos_nemico2.c='H';
    pos_nemico2.xi=x;
    pos_nemico2.xf=x+G-1;
    pos_nemico2.y=y;
    pos_nemico2.p=i;
    pos_nemico2.pid=pthread_self();
    
    for(j=0;j<G;j++)
         pos_nemico2.nem_vivi[j]=2;
    
    if(!(i%2)) // se il numero assegnato al nemico è pari
      {
        pos_nemico2.DIRX=1; // vÃ_ a destra
        SOGLIAX=MAXX-1; // e la soglia max in x è MAXX-1
      }
    else // altrimenti
       {
         pos_nemico2.DIRX=-1; // vÃ_ a sinistra
         SOGLIAX=1; // e la soglia max in x è 1
       }
    
    sem_wait(&disponibili);
    pthread_mutex_lock(&mutex);
    buffer[IN] = pos_nemico2;
    IN=(IN+1)%BUFFER_DIM;
    sem_post(&presenti); // incrementa il semaforo
    pthread_mutex_unlock(&mutex);
    
    
    while(1)
    {
         if(pos_nemico2.xf>=MAXX-1 || pos_nemico2.xi<=1) // se il nemico sbatte contro una parete laterale
           {
             pos_nemico2.DIRX*=-1; // cambio la direzione
             if(SOGLIAX==MAXX-1) // se la nuova direzione è destra
                SOGLIAX=1; // la soglia è MAXX-1
             else // altrimenti
                SOGLIAX=MAXX-1; // la soglia è 1
           }  
    
         if(pos_nemico2.DIRX==1) // se la direzione è destra
           dx=PASSO; // il suo spostamento sarÃ_ di PASSO
         else // altrimenti
           dx=-PASSO; // il suo spostamento sarÃ_ di -PASSO
          
         pos_nemico2.xi+=dx; // scriviamo la posizione in x del primo nemico
         pos_nemico2.xf+=dx; // scriviamo la posizione in x dell'ultimo nemico
    
         if(!(time_giu%SOGLIA_GIU)) // ad intervalli regolari
           {
             dy=PASSO; // il nemico avanza di PASSO verso la soglia massima in Y
             time_giu=1; // riazzero il contatore
           }
        else
           {
             dy=0; // il nemico non avanza verso la soglia massima in Y
             time_giu++; // aggiorno il contatore per la discesa del nemico
           }
    
        pos_nemico2.y+=dy; // scriviamo la posizione in y del nemico
    
        // aggiorniamo la posizione del nemico e la comunichiamo al controllo
        sem_wait(&disponibili);
        pthread_mutex_lock(&mutex);
        buffer[IN] = pos_nemico2;
        IN=(IN+1)%BUFFER_DIM;
        sem_post(&presenti); // incrementa il semaforo
        pthread_mutex_unlock(&mutex);
    
    
        if(!(time_bomb%SOGLIA_BOMB)){ // ad intervalli regolari
            pos.x = pos_nemico2.x;
    	pos.y = pos_nemico2.y;
            pthread_create(&bomba_id, NULL, &bomba_func, &pos); 
    	//pthread_join(bomba_id, NULL);
                                    }
        time_bomb++; // aggiorno il contatore per la bomba
    
        usleep(300000);
    
    } // fine while
    
    } // fine funzione Nemico2
    
    /** Funzione CONTROLLO **/
    void * controllo_func(void * arg)
    {
    pos astronave, missile[2], bomba, nemico[M], nem2[M], valore_letto;
    args pos;
    int GAME_OVER=0; // se game_over=-1 l'astronave è stata uccisa, se game_over=1 l'astronave ha vinto, se game_over=0 il gioco prosegue
    int NEM_VIVI=M+M*G; // segna quanti nemici vivi ci sono
    int vita_gruppo[M]; // vettore che indica lo stato di vita del gruppo iesimo
    int i,j;
    int vite[M][G];
    pthread_t nemico2_id[M];
    
    
    init_pair(1,COLOR_GREEN,COLOR_BLACK);
    init_pair(2,COLOR_CYAN,COLOR_BLACK);
    init_pair(3,COLOR_YELLOW,COLOR_BLACK);
    init_pair(4,COLOR_RED,COLOR_BLACK);
    init_pair(5,COLOR_BLUE,COLOR_BLACK);
    init_pair(6,COLOR_MAGENTA,COLOR_BLACK);
    
    astronave.x=-1;
    
    for(i=0;i<2;i++)
        missile[i].x=-1;
    
    for(i=0;i<M;i++)
       {
          nemico[i].x=-1;
          nemico[i].vita=1;
       
          nem2[i].xf=-1;
          nem2[i].vita=2;
    
          vita_gruppo[i]=4;
        }
    
    for(i=0;i<M;i++)
       for(j=0;j<G;j++)
          vite[i][j]=2;
    
    do
    {
        sem_wait(&presenti);
        pthread_mutex_lock(&mutex);
        valore_letto = buffer[OUT];
        OUT=(OUT+1)%BUFFER_DIM;
        sem_post(&disponibili); // incrementa il semaforo
        pthread_mutex_unlock(&mutex);
    
    switch(valore_letto.c) {
               
                case '#': /** CASO ASTRONAVE **/
                                if(astronave.x>=0) // se l'astronave è giÃ_ entrata in scena
                                    {
                                       // cancello la "vecchia" posizione dell'astronave
                                       mvaddch(astronave.y,astronave.x,' ');
                                    }
                                astronave=valore_letto; // aggiorno la sua nuova posizione
    			    attron(COLOR_PAIR(5));
                                mvaddch(astronave.y,astronave.x,astronave.c); // e la visualizzo
                                break;
    
    
                case '*': /** CASO MISSILE **/
                              missile[valore_letto.p]=valore_letto; // aggiorno la sua nuova posizione
                              if(valore_letto.p%2)       
                                 mvaddch(missile[valore_letto.p].y+1,missile[valore_letto.p].x-1,' '); //cancello la "vecchia" posizione del missile
                              else
                                 mvaddch(missile[valore_letto.p].y+1,missile[valore_letto.p].x+1,' '); //cancello la "vecchia" posizione del missile
                                                  
                              /** ----------------------------------- Controllo collisioni ----------------------------------- **/
    
                              /** missile -> pareti **/
                              if(missile[valore_letto.p].x>MAXX-1 || missile[valore_letto.p].x<0 || missile[valore_letto.p].y<0) // se il missile raggiunge uno dei bordi laterali o quello superiore
                                 {
                                    mvaddch(missile[valore_letto.p].y,missile[valore_letto.p].x,' '); // lo cancello
                                    pthread_cancel(missile[valore_letto.p].pid); // e uccido il processo
    				pthread_detach(missile[valore_letto.p].pid); // e libero la memoria
                                 }
                              else // altrimenti
    			       {
    				attron(COLOR_PAIR(2));
                                    mvaddch(missile[valore_letto.p].y,missile[valore_letto.p].x,missile[valore_letto.p].c); // lo visualizzo
    			       }
    
                               /** missile->nemico **/
                              for(i=0;i<M;i++)
                               if((missile[valore_letto.p].x==nemico[i].x)&&(missile[valore_letto.p].y==nemico[i].y)&&nemico[i].vita<1)
                                    {
                                        mvaddch(nemico[i].y,nemico[i].x,' '); // nascondo il nemico colpito
                                        mvaddch(missile[valore_letto.p].y,missile[valore_letto.p].x,' '); // nascondo il missile che ha colpito il nemico
                                        pthread_cancel(nemico[i].pid); // uccido il processo del nemico
    				    pthread_detach(nemico[i].pid); // e libero la memoria
                                        pthread_cancel(missile[valore_letto.p].pid); // uccido il processo del missile
    				    pthread_detach(missile[valore_letto.p].pid); // e libero la memoria
                                        NEM_VIVI--; // decremento il numero dei nemici vivi
                                        nemico[i].vita=0; // metto lo stato di vita del nemico colpito a 0
    				    pos.x = nemico[i].x;
    				    pos.y = nemico[i].y;
    				    pos.i = nemico[i].p;
    				    pthread_create(&nemico2_id[nemico[i].p], NULL, &nemico2_func, &pos); 
    				    //pthread_join(nemico2_id[nemico[i].p], NULL);                                    
                                    }
    
                                /** missile -> nemico2 **/
                                for(i=0;i<M;i++) // per ogni nemico di secondo livello
                                    {
                                      if(nem2[i].xf!=-1) // entrato in scena
                                        {
                                         if((missile[valore_letto.p].x>= nem2[i].xi && missile[valore_letto.p].x<=nem2[i].xf) &&(missile[valore_letto.p].y==nem2[i].y)) // controllo se il nemico2 è stato colpito dal nemico
                                                    {
                                                      j=missile[valore_letto.p].x-nem2[i].xi; // verifico quale nemico del proprio gruppo è stato colpito
                                                      if(vite[i][j]>0) // verifico che il nemico abbia ancora vite
                                                        {
    						     vite[i][j]--; // decremento il valore delle sue vite
    						     if(vite[i][j]<1) // se il valore delle sue vite è arrivato a zero
    							{
    							 vita_gruppo[i]--; // la vita del suo gruppo viene decrementata
    							 NEM_VIVI--; // e anche il numero dei nemici vivi
    							}
    						    } // fine controllo sulla vita del nemico colpito
                                                                                                     
                                                    if(vita_gruppo[i]<1){ // se la vita del gruppo è minore di 1
    						    pthread_cancel(nem2[i].pid); // uccido il thread del gruppo dei nemici di 2° livello
    						    pthread_detach(nem2[i].pid); // e libero la memoria allocata
    						    } // fine controllo sulla vita del gruppo
    
                                                    } // fine controllo sullo scontro missile->nemico2[i]
                                         } // fine controllo sull'entrata in scena del nemico2[i]
                                   } // fine for
                                                                  
                              break;
    case 'H': /** CASO NEMICO2 **/
                              if(nem2[valore_letto.p].xf>=0)
                                for(i=0;i<G;i++)
                                    mvaddch(nem2[valore_letto.p].y,nem2[valore_letto.p].xi+i,' '); // cancello la vecchia posizione
    
                              nem2[valore_letto.p]=valore_letto; // assegno il nuovo valore al nemico2
                              
                              for(i=0;i<G;i++)
                                   {
                                     if(vite[valore_letto.p][i]>0) // se il singolo nemico nel gruppo è ancora vivo
    				   {
    				    if(vite[valore_letto.p][i]==2)
    				      attron(COLOR_PAIR(6));
    				    else
    				      attron(COLOR_PAIR(3));
                                        mvaddch(nem2[valore_letto.p].y,nem2[valore_letto.p].xi+i,nem2[valore_letto.p].c); // lo disegno
    				   }
                                     else // altrimenti
                                        mvaddch(nem2[valore_letto.p].y,nem2[valore_letto.p].xi+i,' '); // no
                                   }
    
                /** ----------------------------------- Controllo collisioni ----------------------------------- **/
    
                             // nemico2 -> astronave
                             if(nem2[valore_letto.p].y==astronave.y) // se il nemico raggiunge la linea dell'astronave
                                {
                                  pthread_cancel(nemico[valore_letto.p].pid); // uccido il nemico2
    			      pthread_detach(nemico[valore_letto.p].pid); // e libero la memoria
                                  pthread_cancel(astronave.pid); // uccido l'astronave
    			      pthread_detach(astronave.pid); // e libero la memoria
                                  GAME_OVER=-1; // l'astronave ha perso
                                }
    
                            break;
    (continua...)
    Mau

  3. #3
    (...continuo)

    codice:
              case 'o':   /** CASO BOMBA **/
                                 
                              bomba=valore_letto; //assegno il nuovo valore di bomba
                              mvaddch(bomba.y-1,bomba.x,' '); //cancello la vecchia posizione
    
                              /** ----------------------------------- Controllo collisioni ----------------------------------- **/
    
                              // bomba -> astronave
                              if(bomba.y==MAXY)  //se la bomba ha raggiunto la penultima posizione nello schermo
                                {
                                  if(bomba.x==astronave.x)   //verifica se ha colpito l'astronave e in caso affermativo il gioco termina e l'astronave ha perso
                                      GAME_OVER=-1;
                                  pthread_cancel(bomba.pid); //uccido il processo bomba
    			      pthread_detach(bomba.pid); // e libero la memoria
                                }
                              else //altrimenti
    			      {
    				attron(COLOR_PAIR(4));
                                    mvaddch(bomba.y,bomba.x,bomba.c); //stampo la nuova posizione
    			      }
                              break;
    
    
              case '$': /** CASO NEMICO **/
                             if(nemico[valore_letto.p].x>=0) // se il nemico è giÃ_ entrato in scena
                                 mvaddch(nemico[valore_letto.p].y,nemico[valore_letto.p].x,' ');  // cancello la "vecchia" posizione del nemico
                                
                             nemico[valore_letto.p]=valore_letto; // aggiorno la posizione del nemico
    			 attron(COLOR_PAIR(1));
                             mvaddch(nemico[valore_letto.p].y,nemico[valore_letto.p].x,nemico[valore_letto.p].c); // e lo visualizzo
    
                             /** ----------------------------------- Controllo collisioni ----------------------------------- **/
    
                             // nemico -> astronave
                             if(nemico[valore_letto.p].y==astronave.y) // se il nemico raggiunge la linea dell'astronave
                                {
                                  pthread_cancel(nemico[valore_letto.p].pid); // uccido il nemico
    			      pthread_detach(nemico[valore_letto.p].pid); // e libero la memoria
                                  pthread_cancel(astronave.pid); // uccido l'astronave
    			      pthread_detach(astronave.pid); // e libero la memoria
                                  GAME_OVER=-1; // l'astronave ha perso
                                }
    
                             break;
               
    
                                         } // fine switch
    
    if(!NEM_VIVI) // se NEM_VIVI è uguale a 0
      GAME_OVER=1; // l'astronave ha vinto
    
    curs_set(0);
    refresh();
    } // fine do
    while(!GAME_OVER);
    
    if(GAME_OVER>0)
      {
        mvaddstr(MAXY/2, MAXX/2-3,"HAI VINTO!");
        refresh();
        fflush(stdin);
        getchar();
      }
    else
      {
        mvaddstr(MAXY/2, MAXX/2-3,"HAI PERSO!");
        refresh();
        fflush(stdin);
        getchar();
      }
    
    } // fine Funzione Controllo
    fine....so che è lunghetto..ma vi pregoooo!!dateci uno sguardo!
    Mau

  4. #4
    Utente di HTML.it L'avatar di linoma
    Registrato dal
    Mar 2010
    Messaggi
    1,346
    Usa gdb.
    Per gli Spartani e Sparta usa spartan Il mio github

  5. #5
    Si infatti l'errore è detettato alla linea 304:
    codice:
    Program received signal SIGFPE, Arithmetic exception.
    [Switching to Thread 0xb76c8b90 (LWP 4387)]
    0x08049595 in nemico_func (arg=0xbf9afd30) at s.c:304
    304	    if(!(time_giu%SOGLIA_GIU)) // ad intervalli regolari
    Ho provato a settare alla linea 254 time_giu a 1 invece che a 0 e il programma sembra funzionare.. I $ si muovono e con la barra spara Ho trovato come non fare una banana...

    EDIT: Cmq ho rilevato un comportamento strano: ritornando a settare time_giu a 0 e ricompilare, il programma funziona ugualmente.. :master:

  6. #6
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    Originariamente inviato da simo_us

    Ho provato a settare alla linea 254 time_giu a 1 invece che a 0
    Non penso che il problema (Arithmetic exception) sia per time_giu ... molto più probabilmente è SOGLIA_GIU che diventa 0 in determinati casi, causando una divisione per zero durante il calcolo del modulo.
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  7. #7
    si..ho provato anche io e anche a me dava quell'errore...l'ho corretto ma poi, provandolo con run di gdb, tornavano gli stessi errori.. praticamente se colpisco un nemico di primo livello, si formano i 4 nemici di secondo livello, colpisco e uccido quei 4 nemici e poi quando uccido il nemico di primo livello rimasto và in segmentation fault...
    Mau

  8. #8
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    Va bene "descrivere la dinamica del gioco" ma devi rimediare all'errore che ti è stato segnalato ... non ho capito come hai fatto ... cosa hai modificato nel codice?
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  9. #9
    Originariamente inviato da mapulce
    và in segmentation fault...
    Compila con i warning al massimo, ad esempio
    al posto di:
    codice:
    typedef struct pos
         {
    ... 
            int pid; // pid del processo
    metti
    codice:
    typedef struct pos
         {
    ... 
            pthread_t pid; // pid del processo
    visto che gli assegni il valore restituito da
    codice:
    pthread_t pthread_self(void);
    riduci la lunghezza delle funzioni e... controlla TUTTI gli errori logici e runtime.
    semplice no? ;-)

  10. #10
    Originariamente inviato da oregon
    Va bene "descrivere la dinamica del gioco" ma devi rimediare all'errore che ti è stato segnalato ... non ho capito come hai fatto ... cosa hai modificato nel codice?
    Ho modificato la generazione casuale di SOGLIA_GIU
    codice:
    int SOGLIA_GIU=10*(0+rand()%4)+i*5; // soglia per far scendere il nemico di una riga
    con

    codice:
    int SOGLIA_GIU=10*(1+rand()%4)+i*5; // soglia per far scendere il nemico di una riga
    visto che nel primo caso mi avrebbe potuto dare come valore 0 e in seguito fare divisioni per 0...
    Ma il problema della segmentation fault rimane..Tra l'altro cercare gli errori con dbg è un casino perchè mentre il programma è in esecuzione, vengono stampate a video (sopra lo "schermo di gioco") mille scritte sui thread generati e non si capisce niente!
    Mau

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.