ERRORE: Segmentation fault, Gioco di scacchi con l'uso delle LISTE

di il
4 risposte

ERRORE: Segmentation fault, Gioco di scacchi con l'uso delle LISTE

Salve a tutti, stavo cercando di scrivere un codice per giocare a scacchi che utilizzi solo le liste, il compilatore non restituisce alcun errore, ma quando lo eseguo compare: "Program received signal SIGSEGV, Segmentation fault", in questo punto: head->dato = bT....
stesso errore se utilizzo la funzione modifica....
Sinceramente non so quale sia il problema...
Spero che qualcuno riesca a chiarirmi un po le idee GRAZIE....


#define BRD_SQ_NUM 120

#define START_FEN  "tcadract/pppppppp/8/8/8/8/PPPPPPPP/TCADRACT w RDrd - 0 1"

//char *NomePezzo[] = { " ","\u265F", "\u265E", "\u265D", "\u265C", "\u265B", "\u265A", "\u2659", "\u2658",  "\u2657", "\u2656", "\u2655", "\u2654"}; /* codifica unicode per linux */
#define NomePezzo  " PCATDRpcatdr" /* codifica ASCII per windows */
#define latoChar "wb-"
#define RigaChar  "12345678"
#define ColonnaChar  "abcdefgh"

#define SUDESTRA 9
#define SUSINISTRA 11
#define GIUDESTRA -11
#define GIUSINISTRA -9
#define SU 10
#define SINISTRA 1
#define GIU -10
#define DESTRA -1

enum { EMPTY, wP, wC, wA, wT, wD, wR, bP, bC, bA, bT, bD, bR  };
enum { COLONNA_A, COLONNA_B, COLONNA_C, COLONNA_D, COLONNA_E, COLONNA_F, COLONNA_G, COLONNA_H, COLONNA_NONE };
enum { RIGA_1, RIGA_2, RIGA_3, RIGA_4, RIGA_5, RIGA_6, RIGA_7, RIGA_8, RIGA_NONE };

enum { WHITE, BLACK, BOTH };


enum {
  A1 = 21, B1, C1, D1, E1, F1, G1, H1,
  A2 = 31, B2, C2, D2, E2, F2, G2, H2,
  A3 = 41, B3, C3, D3, E3, F3, G3, H3,
  A4 = 51, B4, C4, D4, E4, F4, G4, H4,
  A5 = 61, B5, C5, D5, E5, F5, G5, H5,
  A6 = 71, B6, C6, D6, E6, F6, G6, H6,
  A7 = 81, B7, C7, D7, E7, F7, G7, H7,
  A8 = 91, B8, C8, D8, E8, F8, G8, H8, NO_SQ, OFFBOARD
};

enum { FALSE, TRUE };

enum { WRCA = 1, WDCA = 2, BRCA = 4, BDCA = 8 };



typedef struct MOVE {
	char lettera;
	int from;
	int to;
	int cattura;
	int arrocco;
	int promozione;
	int enpassant;
	int pedonestart;
} MOVE_T;

typedef struct MOVE_NODE {
	MOVE_T move;
    struct MOVE_NODE *next;
} MOVE_NODE_T;

typedef struct ANNULLA {
	
    MOVE_T move;
	int arrocco;
	int enPas;
	int cinquantaMosse;
	int lato;
	int posKey;
    struct ANNULLA *next;

} ANNULLA_T;

struct nodo{
    int dato; //campo informativo di tipo intero che contiene i pezzi
    struct nodo *next; //puntatore al prossimo nodo della lista
};



typedef struct BOARD {

	int *reSq;

	int lato;
	int enPas;
	int cinquantaMosse;

	int arrocco; //se il re puo' arroccare o meno

	int posKey;

	ANNULLA_T *history;

} BOARD_T;

void inserisci_testa (struct nodo** head, int elem){
    //alloco il nuovo nodo
    struct nodo* new_head;
    new_head = (struct nodo*)malloc(120*sizeof(struct nodo));    
    new_head->dato = elem;    
    new_head->next = *head;   
    *head = new_head;  
}

int accesso_posizione_x(struct nodo* head, int pos){

	int i=1,j=0;
        while((head!=NULL)&&(i<pos)){
                head=head->next;
                i++;
        }
        j=head->dato;
        return j;

}

int modifica (struct nodo* head, int elemento_da_trovare, int nuovo_valore){
    //posso usare head per scorrere la lista perche' e' una copia
    //arrivo fino alla fine oppure fino a quando non ho trovato l'elemento
    while ((head != NULL) && (head->dato != elemento_da_trovare)){
        //scorro la lista
        head = head->next;
    }
    //se la lista era vuota oppure non ho trovato l'elemento restituisco 1
    if(head == NULL)
        return 1;
    //se l'elemento esiste ne sostituisco il valore
    head->dato = nuovo_valore;
    return 0;
}

#define FR2SQ(f,r) ( (21 + (f) ) + ( (r) * 10 ) )
#define SQ64(sq120) (Sq120ToSq64[(sq120)])
#define SQ120(sq64) (Sq64ToSq120[(sq64)])
#define a accesso_posizione_x(pieces, sq)
#define OFFBOARD(a) (a == OFFBOARD)
#define pezzoISCOLOR(a, color) (pezzoCol[a] == color)

void ClearHistory(BOARD_T *pos) {
	ANNULLA_T *current = pos->history;
	ANNULLA_T *next = NULL;
	while(current != NULL) {
		next = current->next;
		free(current);
		current = next;
	}
	pos->history = NULL;
}


void ResetBoard(BOARD_T *pos, struct nodo* head) {

	int index,colonna,righe,sq,k=0;

	for(index = 0; index < BRD_SQ_NUM; ++index) {
		inserisci_testa(&head, OFFBOARD);
	
	}
	
	for(righe = RIGA_8; righe >= RIGA_1; righe--) {
		for(colonna = COLONNA_A; colonna <= COLONNA_H; colonna++) {
			sq = FR2SQ(colonna,righe);
			while((head!=NULL)&&(k<sq)){
			head=head->next;
			k++;
			}
			head->dato=EMPTY;
			
		}
	}

	pos->reSq[WHITE] = pos->reSq[BLACK] = OFFBOARD;

	pos->lato = BOTH;
	pos->enPas = OFFBOARD;
	pos->cinquantaMosse = 0;
	pos->arrocco = 0;
	pos->posKey = 0;    
	ClearHistory(pos);
}


int ParseFen(char *fen, BOARD_T *pos, struct nodo* head) {

	ResetBoard(pos, head);

	int  righe = RIGA_8;
    	int  colonna = COLONNA_A;
    	int  pezzo = 0;
    	int  count = 0;
    	int  i = 0, t=0;
	int  sq64 = 0;
	int  sq120 = 0;
    	int k=0;
    
	while ((righe >= RIGA_1) && *fen) {
	    count = 1;
	    pezzo=0;
	    for (i = 0; i < count; i++) {
			sq120 = FR2SQ(colonna, righe);
            if (pezzo != EMPTY) {
            while((head!=NULL)&&(t<sq120)){
                head=head->next;
                t++;
        	}
        	(head->dato)=pezzo;
        	
				
            }
			colonna++;
        }
		switch (*fen) {
            case 'p': head->dato = bP; break;
            case 't': head->dato = bT; break;
            case 'c': head->dato = bC; break;
            case 'a': head->dato = bA; break;
            case 'r': head->dato = bR; break;
            case 'd': head->dato = bD; break;
            case 'P': head->dato = wP; break;
            case 'T': head->dato = wT; break;
            case 'C': head->dato = wC; break;
            case 'A': head->dato = wA; break;
            case 'R': head->dato = wR; break;
            case 'D': head->dato = wD; break;

            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
                pezzo = EMPTY;
                count = *fen - '0';
                break;

            case '/':
            case ' ':
                righe--;
                colonna = COLONNA_A;
                fen++;
                continue;

            default:
                printf(" FEN error \n");
                return -1;
        }

		for (i = 0; i < count; i++) {
			sq120 = FR2SQ(colonna, righe);
            if (pezzo != EMPTY) {
                    	
				if(pezzo == wR) {
					pos->reSq[WHITE] = sq120;
				}
				if(pezzo == bR) {
					pos->reSq[BLACK] = sq120;
				}
            }
			colonna++;
        }
		fen++;
	}
	pos->lato = (*fen == 'w') ? WHITE : BLACK;
	fen += 2;

	for (i = 0; i < 4; i++) {
        if (*fen == ' ') {
            break;
        }
		switch(*fen) {
			case 'R': pos->arrocco |= WRCA; break;
			case 'D': pos->arrocco |= WDCA; break;
			case 'r': pos->arrocco |= BRCA; break;
			case 'd': pos->arrocco |= BDCA; break;
			default:	     break;
        }
		fen++;
	}
	fen++;

	if (*fen != '-') {
		colonna = fen[0] - 'a';
		righe = fen[1] - '1';
		pos->enPas = FR2SQ(colonna,righe);
    }

	pos->posKey = GenPositionKey(pos,head);

    PrintBoard(pos, head);

	return 0;
}

4 Risposte

  • Re: ERRORE: Segmentation fault, Gioco di scacchi con l'uso delle LISTE

    Quell'errore avviene solo a runtime (il compilatore non lo può segnalare prima) ed è causato da un valore di puntatore non corretto (in genere nullo).

    Devi controllare con il debugger (o con delle printf) il valore dei puntatori coinvolti nella linea di codice coinvolto e cercare di capire perché il valore del puntatore non è quello che ti aspetti.
  • Re: ERRORE: Segmentation fault, Gioco di scacchi con l'uso delle LISTE

    Manca un pezzo di codice.

    Come fate a scrivere centinaia di righe di codice senza testarle? Se sbaglio qualche puntatore in qualche funzione, poi mi conviene cercare di scoprirlo a posteriori tipo ago nel pagliaio?

    comunque
    
                while((head!=NULL)&&(t<sq120)){
                    head=head->next;
                    t++;
            	}
            	(head->dato)=pezzo;
    
    se esci da questi cicli quando head == NULL, poi il segmentation fault è la logica conseguenza quando esegui (head->dato)=pezzo;

    Controlla tutte queste cose
  • Re: ERRORE: Segmentation fault, Gioco di scacchi con l'uso delle LISTE

    Avevo scritto il codice inizialmente su dev c++, e funzionava perfettamente, non dava errori ne compilandolo ne eseguendolo(*ora deduco che dev ha qualche problema), poi volevo attuare dei miglioramenti a livello grafico, utilizzando la codifica unicode e lo riscritto su linux, dove mi riporta questo errore...

    in teoria la scacchiera dovrebbe essere tutta vuota, ovvero nella lista ci sono solo EMPTY, dovo aver eseguito la funzione resetboard, che poi vado a modificare con i pezzi giusti, il primo è bT che corrisponde al numero 10, e fino a qui funziona, poi non capisco bene: head->dato=pezzo ma qui da l'errore eseguendo il programma con un debugger...

    però non sto assegnando a quella cella il contenuto della variabile pezzo???
    
    #define START_FEN  "tcadract/pppppppp/8/8/8/8/PPPPPPPP/TCADRACT w RDrd - 0 1"
    
    void ResetBoard(BOARD_T *pos, struct nodo* head) {
    
    	int index,colonna,righe,sq,k=0;
    
    	for(index = 0; index < BRD_SQ_NUM; ++index) {
    		inserisci_testa(&head, OFFBOARD);
    	
    	}
    	
    	for(righe = RIGA_8; righe >= RIGA_1; righe--) {
    		for(colonna = COLONNA_A; colonna <= COLONNA_H; colonna++) {
    			sq = FR2SQ(colonna,righe);
    			while((head!=NULL)&&(k<sq)){
    			head=head->next;
    			k++;
    			}
    			head->dato=EMPTY;
    			
    		}
    	}
    
    	pos->reSq[WHITE] = pos->reSq[BLACK] = OFFBOARD;
    
    	pos->lato = BOTH;
    	pos->enPas = OFFBOARD;
    	pos->cinquantaMosse = 0;
    	pos->arrocco = 0;
    	pos->posKey = 0;    
    	ClearHistory(pos);
    }
    
    
    int ParseFen(char *fen, BOARD_T *pos, struct nodo* head) {
    
    	ResetBoard(pos, head);
    
    	int  righe = RIGA_8;
        	int  colonna = COLONNA_A;
        	int  pezzo = 0;
        	int  count = 0;
        	int  i = 0, t=1;
    	int  sq64 = 0;
    	int  sq120 = 0;
        	int k=0;
        
    	while ((righe >= RIGA_1) && *fen) {
    	    count = 1;
    	    pezzo=0;
    	    
    		switch (*fen) {
                case 'p': pezzo = bP; break;
                case 't': pezzo = bT; break;
                case 'c': pezzo = bC; break;
                case 'a': pezzo = bA; break;
                case 'r': pezzo = bR; break;
                case 'd': pezzo = bD; break;
                case 'P': pezzo = wP; break;
                case 'T': pezzo = wT; break;
                case 'C': pezzo = wC; break;
                case 'A': pezzo = wA; break;
                case 'R': pezzo = wR; break;
                case 'D': pezzo = wD; break;
    
                case '1':
                case '2':
                case '3':
                case '4':
                case '5':
                case '6':
                case '7':
                case '8':
                    pezzo = EMPTY;
                    count = *fen - '0';
                    break;
    
                case '/':
                case ' ':
                    righe--;
                    colonna = COLONNA_A;
                    fen++;
                    continue;
    
                default:
                    printf(" FEN error \n");
                    return -1;
            }
    
    		for (i = 0; i < count; i++) {
    			sq120 = FR2SQ(colonna, righe);
                if (pezzo != EMPTY) {
                        	
                while((head!=NULL)&&(t<=sq120)){
                    head=head->next;
                    t++;
            	}
            	head->dato=pezzo;
            	
    				
    				if(pezzo == wR) {
    					pos->reSq[WHITE] = sq120;
    				}
    				if(pezzo == bR) {
    					pos->reSq[BLACK] = sq120;
    				}
                }
    			colonna++;
            }
    		fen++;
    	}
    	pos->lato = (*fen == 'w') ? WHITE : BLACK;
    	fen += 2;
    
    	for (i = 0; i < 4; i++) {
            if (*fen == ' ') {
                break;
            }
    		switch(*fen) {
    			case 'R': pos->arrocco |= WRCA; break;
    			case 'D': pos->arrocco |= WDCA; break;
    			case 'r': pos->arrocco |= BRCA; break;
    			case 'd': pos->arrocco |= BDCA; break;
    			default:	     break;
            }
    		fen++;
    	}
    	fen++;
    
    	if (*fen != '-') {
    		colonna = fen[0] - 'a';
    		righe = fen[1] - '1';
    		pos->enPas = FR2SQ(colonna,righe);
        }
    
    	pos->posKey = GenPositionKey(pos,head);
    
        PrintBoard(pos, head);
    
    	return 0;
    }
  • Re: ERRORE: Segmentation fault, Gioco di scacchi con l'uso delle LISTE

    Se head è NULL, con head->dato = X; stai tentando di andare a scrivere X sull'indirizzo zero, che tipicamente è l'inizio dell'hard disk e lì non ci puoi scrivere altrimenti il sistema operativo non parte.
Devi accedere o registrarti per scrivere nel forum
4 risposte