Errore di segmentazione (core dump creato) please help me

Linguaggi di programmazione: php, perl, python, C, bash e tutti gli altri.
bobocop
Prode Principiante
Messaggi: 7
Iscrizione: giovedì 31 maggio 2012, 11:18

Errore di segmentazione (core dump creato) please help me

Messaggio da bobocop »

raga non capisco dove stà l'errore anche perché sul notebook di alcuni colleghi funzionava.....è un pò lungo ma vi prego datemi una mano.....

Codice: Seleziona tutto

#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <errno.h>
#include <unistd.h>
#include <pthread.h>
#include <malloc.h>
#include <sys/socket.h>
#include <string.h>
#include <time.h>
#include <netinet/ip.h>
#include <sys/stat.h>
#include <fcntl.h>

typedef struct{  //definizione struttura carta 

	int val;
	int seme;
	int qta;

}cardstruct;

typedef cardstruct* carta;	//carta è il puntatore a alla struttura cardstruct

// VARIABILI CONDIVISE DAI THREADS

int numplayers;				        //numero di giocatori
char **utenti;					//vettore che conserva i nickname dei giocatori correnti
int *fd; 					//vettore dei file descriptor dei giocatori
int *fiches;					//vettore che conserva le fiches dei giocatori
int *bet;					//vettore che conserva la puntata dei giocatori
int *punteggio;					//vettore che conserva il punteggio dei giocatori
time_t inizio;					//variabile contenente l'inizio effettivo del gioco
struct sockaddr_in indirizzo_client; 		//struttura dati con informazioni sui client
socklen_t client_size=sizeof(indirizzo_client); //grandezza struttura dati informazioni sui client
pthread_mutex_t mut= PTHREAD_MUTEX_INITIALIZER; //semaforo sul numero dei giocatori
pthread_cond_t cond= PTHREAD_COND_INITIALIZER;	//condizione che indica se c'e' almeno un giocatore
int fdlog;					//file descriptor del file di log


// ******************************** INIZIO FUNZIONI ****************************************


//la funzione riceve in ingresso un vettore carte e lo restituisce inizializzato
carta* init_mazzo(carta* carte){
int i,j;

carte=malloc(53*sizeof(carta));		//allochiamo memoria per i puntatori

for (i=0;i<54;i++)
	{
	carte[i]=(carta)malloc(sizeof(cardstruct));	//allochiamo memoria per i record
	}

carte[0]->val=52;		//numero di carte che differiscono per seme e valore

for (i=0;i<4;i++)
	{
	for (j=1;j<14;j++)
		{			//inizializzo i 2 mazzi prima dell'estrazione
		carte[(i*13)+j]->seme=i;
		carte[(i*13)+j]->val=j;
		carte[(i*13)+j]->qta=2;
		}
	}

return carte;
}

//restituisce 0 se le carte sono meno di 52
int test_numcarte(carta* carte){
int i,temp=0;

for (i=1;i<=carte[0]->val;i++)
	{
	temp=temp+carte[i]->qta;
	}

if (temp<=52) return 0;
else return 1;
}

//restituisce il puntatore ad un elemento di carte a caso decrementando la quantita'
carta get_carta(carta* carte){
int i;
carta temp;
i=(((rand()) % (carte[0]->val))+1);	 //prendi un indice i qualsiasi sul range di carte diverse rimanenti
carte[i]->qta--;			 //decrementa la quantita' della iesima carta perche' selezionata

if (carte[i]->qta==0)			 //se e' l'ultima
	{
	temp=carte[i];                   //scambiala con l'ultima carta del mazzo
	carte[i]=carte[carte[0]->val];
	carte[carte[0]->val]=NULL;
	carte[0]->val--;		 //decrementa il range
	return (temp);			 //restituiscila
	}

return (carte[i]);			//altrimenti restituiscila senza toccare le rimanenti
}


//invia a tutti i client collegati un messaggio
void inviamsg(int gi,int *fd,char *buff,int len){
int i,rd;

for(i=1;i<=gi;i++)
	{
	rd=write(fd[i],buff,len);
	if (rd<0) {perror("write");return;}
	}

return;
}

//invia un messaggio a tutti tranne che a "no"
void inviamsg_mod(int g,int *fd,int no,char buff[30],int len){
int i,rd;

rd=0;

for(i=1;i<=g;i++)
	{
	if (i!=no)
		{
		rd=write(fd[i],buff,len);
		}
	if (rd<0) {perror("write");return;}
	}

return;
}

//inpacchetta un messaggio di tipo print
void set_msg(char messaggio[30],int val,int seme){
char temp[30];

strcpy(messaggio,"print ");
sprintf(temp,"%d ",val);
strcat(messaggio,temp);          //ESEMPIO MESSAGGIO "print 5 2^"
sprintf(temp,"%d",seme);
strcat(messaggio,temp);
strcat(messaggio,"^");
}

//conta il punteggio progressivo di un singolo giocatore
int calcola_punteggio(int fd,int val,int punteggio,int *assi){
char buff[30];
int rd;

if (val!=1)
	{
	if ((val)>10){punteggio=punteggio+10;}	//le carte>10 valgono 10
	else {punteggio=punteggio+val;}		//altrimenti hanno il loro valore normale
	}
else
	{
	(*assi)++;				//salviamo il numero di assi usciti
	punteggio+=11;		//sommiamo 11 punti per ogni asso uscito
	}
		
while(1)
	{
	if ((punteggio>21)&&(*assi>0))	//ora se abbiamo sballato per via di un asso
		{
		punteggio-=10;		//possiamo sempre decidere di farlo valere 1
		(*assi)--;				//quindi decrementiamo e ripetiamo finche' abbiamo assi
		}
	else {break;}
	}

if (punteggio>21)			//se il precedente passaggio non basta
	{		
	punteggio=-1;		//abbiamo "sballato"
	rd=write(fd,"over^",5);	//informiamo il client di tale evento
	if (rd<0) {perror("write");return;}
	rd=read(fd,buff,3);
	if (rd<0) {perror("read");return;}
	return -1;
	}
else
	{
	rd=write(fd,"ok^",3);
	if (rd<0) {perror("write");return;}
	rd=read(fd,buff,3);
	if (rd<0) {perror("read");return;}
	}

return punteggio;
}


//simula la giocata del banco
int play_banco(int *fd,int players,carta carta_server,carta* mazzo){
char tmp[30],msg[30];
int assi, punteggio, rd, i;
carta carta_tmp;

strcpy(tmp,"");
strcpy(msg,"server ");
assi=0;
punteggio=0;

while(punteggio<=17)
	{
	if (punteggio==0)
		{
		carta_tmp=carta_server;
		sprintf(tmp,"%d",carta_tmp->val);
		strcat(msg,tmp);
		strcat(msg," ");
		sprintf(tmp,"%d",carta_tmp->seme);
		strcat(msg,tmp);		
		}

	else
		{
		carta_tmp=get_carta(mazzo);
		strcat(msg," ");
		sprintf(tmp,"%d",carta_tmp->val);
		strcat(msg,tmp);
		strcat(msg," ");
		sprintf(tmp,"%d",carta_tmp->seme);
		strcat(msg,tmp);
		}

	if (carta_tmp->val!=1)
		{
		if ((carta_tmp->val)>10){punteggio=punteggio+10;}
		else {punteggio=punteggio+carta_tmp->val;}
		}
	else 
		{
		assi++;
		punteggio+=11;
		}

	while(1)
		{
		if ((punteggio>21)&&(assi>0))
			{
			punteggio-=10;
			assi--;
			}
		else{break;}
		}
		
	if (punteggio>21)
		{
		punteggio=-1;
		break;
		}
	}	

strcat(msg,"^");
inviamsg(players,fd,msg,strlen(msg));

for(i=1;i<=players;i++)
	{
	rd=read(fd[i],msg,3);
	if (rd<0) {perror("read");return;}
	}

return punteggio;
}

//invia ad ogni giocatore il proprio risultato
void invia_risultato(int *fd,int *punteggio,int *bet,int players,int *fiches){
int i,rd;
char msg[30],tmp[30],buffora[30];
char buff[3];
int j;
time_t ora;
int minuti, secondi;
double diff;

j=0;

for (i=1;i<=players;i++)
	{
	if ((punteggio[0]>punteggio[i])||(punteggio[i]==-1))
		{
		fiches[i]-=bet[i];
		strcpy(msg,"lose ");
		}
	else
		{
		if (punteggio[0]<punteggio[i])
			{
			fiches[i]+=bet[i];
			strcpy(msg,"win ");
			}
		else
			{
			strcpy(msg,"draw ");
			}
		}

	sprintf(tmp,"%d",fiches[i]);
	strcat(msg,tmp);
	strcat(msg,"^");
	rd=write(fd[i],msg,strlen(msg));
	if (rd<0) {perror("write");return;}

	/*STATO GIOCO*/

	memset(&tmp,0,sizeof(tmp));
	sprintf(tmp,"%d",players);
	write(fd[i],tmp,sizeof(tmp));		//invia il numero dei giocatori
	if (rd<0) {perror("write");return;}
	rd=read(fd[i],tmp,sizeof(tmp));		//legge ok^
	if (rd<0) {perror("read");return;}
	
	j=1;

	while (j<=players)			//scorre il vettore utenti
		{
		write(fd[i],utenti[j],9);	//invia gli utenti
		if (rd<0) {perror("write");return;}
		j++;
		}

	rd=read(fd[i],tmp,sizeof(tmp));		//legge ok^
	if (rd<0) {perror("read");return;}
	memset(&msg,0,sizeof(msg));
	time(&ora);				//calcolo tempo rimanente
	diff=1200-difftime(ora,inizio);
	minuti=diff/60;
	secondi=(int) diff%60;
	sprintf(buffora,"%d",minuti);
	strcat(msg,buffora);
	strcat(msg,":");
	sprintf(buffora,"%d",secondi);
	strcat(msg,buffora);
	write(fd[i],msg,sizeof(msg));		//invia il tempo rimanente
	if (rd<0) {perror("write");return;}
	rd=read(fd[i],buff,3);
	if (rd<0) {perror("read");return;}

	}

return;
}


//funzione che accetta i client in ingresso
void *connetti_giocatore(void *x){
int players=0;	//la variabile locale del numero giocatori e' inizializzata a zero
int rd,er;
int fdes;
char buff[30];
char ip[15];
int *temp;
char **temp2;

	
while(1)
	{
	if ((listen(fd[0],100))<0)
		{
		perror("listen");
		return 0;
		}

	if ((fdes=(accept(fd[0],(struct sockaddr*) &indirizzo_client,&client_size)))<0)
		{
		perror("accept");
		return 0;
		}

	rd=read(fdes,buff,sizeof(buff));	//legge il nome utente
	if (rd<0) {perror("read");return 0;}

	er=write(fdlog,buff,rd);                //scrive nel file log il nome utente
	if (er<0) {perror("write");return 0;}
	er=write(fdlog," ",1);
	if (er<0) {perror("write");return 0;}
	sprintf(ip,"%d",inet_ntoa(indirizzo_client.sin_addr.s_addr));
	er=write(fdlog,ip,strlen(ip));	 	//scrive nel file log l'indirizzo IP
	if (er<0) {perror("write");return 0;}
	er=write(fdlog,"\n",1);
	if (er<0) {perror("write");return 0;}

	pthread_mutex_lock(&mut);
	numplayers++;
	players=numplayers;

	temp=(int *)realloc(fd, numplayers * sizeof(int));
	if (temp!=NULL)
		{
		fd=temp;
		fd[numplayers]=fdes;
		}
	else {perror("realloc");return 0;}


	temp=(int *)realloc(fiches, numplayers * sizeof(int));			
	if (temp!=NULL)
		{
		fiches=temp;
		fiches[numplayers]=10000;				//assegna le fiches al nuovo giocatore
		}
	else {perror("realloc");return 0;}
		
	temp=(int *)realloc(bet, numplayers * sizeof(int));
	if (temp!=NULL) {bet=temp;}
	else {perror("realloc");return 0;}

	temp=(int *)realloc(punteggio, numplayers * sizeof(int));
	if (temp!=NULL) {punteggio=temp;}
	else {perror("realloc");return 0;}

	temp2=(char **)realloc(utenti,numplayers * sizeof(char));
	temp2[numplayers]=(char *)realloc(utenti,30 * sizeof(char));
	if (temp2!=NULL) 
		{
		utenti=temp2;
		strncpy(utenti[numplayers],buff,rd);		//lo scrive nel vettore
		utenti[numplayers][rd]='\0';
		}
	else {perror("realloc");return 0;}

		
	if (players==1){pthread_cond_broadcast(&cond);} 
	pthread_mutex_unlock(&mut);
		
	}
}

//effettua il countdown per la terminazione del gioco
void *countdown (void *arg){
time_t fine;
double d;


time(&inizio);	//prendo il tempo
time(&fine);	//prendo il tempo

while (d=(difftime(fine,inizio)<1200))
	{
	time(&fine);
	}

*(int *)arg=1;


}



//*********************** FINE FUNZIONI ******************************
		


/****MAIN*****/

int main(int argc,char *argv[]){

char tmp[30];					//stringa temporanea per concatenazione messaggi
char* tmp2;					//stringa temp2
int *tmp3;					//array temporaneo per il controllo dell'uscita
char msg[30];					//messaggio da comporre e inviare al client
pthread_t tid; 				        //tid del thread che accetta le connessioni dai client
int players;                                    //variabile locale che si riferisce a numplayers
int ingioco;					//numero di giocatori che sono in gioco
int i,x;					//indici per i for e while
int rd;					 	//variabile per la gestione dei read e dei write
time_t ora;					//variabile che conterrà l'ora 
int *assi;					//numero di assi nella mano corrente
int porta;					//porta in ascolto
int flag;					//variabile flag per il countdown
int *uscite;					//array per le uscite
int cd;						//variabile per il thread del countdown
char buff[30];					//buffer per la lettura messaggi
carta* mazzo;					//array di puntatori di tipo carta
carta carta_tmp;				//carta estratta
carta carta_server;				//carta estratta dal server
struct sockaddr_in indirizzo;                   //struttura dati con informazioni sul server

//controlla il corretto inserimento della porta

if (argc<=2)
	{
	if (argv[1]!=NULL)
		{
		porta=atoi(argv[1]);
		if (!((porta<=32768)&&(porta>=5000)))
			{
			rd=write(STDERR_FILENO,"ERRORE! La porta deve essere compresa tra 5000 e 32768.\n",57);
			if (rd<0) {perror("write");return 0;}
			return 0;
			}
		}
	else
		{
		rd=write(STDERR_FILENO,"ERRORE! Bisogna fornire la porta su cui mettersi in ascolto (compresa tra 5000 e 32768)\nes: ./server 5200\n",106);
		if (rd<0) {perror("write");return 0;}
		return 0;
		}
	}
else
	{
	rd=write(STDERR_FILENO,"ERRORE DI ESECUZIONE!\nes: ./server 5200\n",40);
	if (rd<0) {perror("write");return 0;}
	return 0;
	}


//apri e scrivi sul file di log l'orario di inizio

fdlog=open("log.txt",O_APPEND|O_CREAT|O_WRONLY,S_IRWXU);
if(fdlog<0){perror("errore di open");return 0;}
time(&ora);
ctime_r(&ora,buff);
rd=write(fdlog,buff,strlen(buff));
if (rd<0) {perror("write");return 0;}
memset(&buff,0,sizeof(buff));

//inizializzazione 
players=0;			//inizializza il numero dei giocatori a 0
mazzo=init_mazzo(mazzo);	//inizializza il mazzo di carte
srand(time(0));			//randomizza per tutte le successive operazioni di random

//struttura della connessione
indirizzo.sin_family=AF_INET;
indirizzo.sin_port=htons(porta);
indirizzo.sin_addr.s_addr=htonl(INADDR_ANY);

fd= (int *)malloc(sizeof(int));	//allocazione memoria per l'array dei file descriptor

fd[0]=socket(PF_INET,SOCK_STREAM,0);  
if (fd[0]<0)
	{
	perror("socket");
	return 0;
	}

if (bind(fd[0],(struct sockaddr *)&indirizzo,sizeof(indirizzo)) < 0 )
	{
	perror("bind");
	return 0;
	}



if ((rd=pthread_create(&tid,NULL,connetti_giocatore,NULL))!=0)   //thread che accetta le connessioni
	{
	printf("%s",strerror(rd));
	}

pthread_mutex_lock(&mut);
pthread_cond_wait(&cond,&mut);	//aspetta finche' non c'e' almeno un giocatore
players=numplayers;		//aggiorna i giocatori
pthread_mutex_unlock(&mut);
	
flag=0;

if ((cd=pthread_create(&tid,NULL,countdown,(void *)&flag))!=0)   //thread che fa partire il countdown
	{
	printf("%s",strerror(cd));
	}

assi=malloc(sizeof(int));

while(players>0)
	{
	tmp3=(int *)realloc(uscite,players * sizeof(int));	//allochiamo la memoria per il vettore "uscite"
	if (tmp3!=NULL) {uscite=tmp3;}
	else {perror("realloc"); return 0;}

	ingioco=1;
	carta_server=get_carta(mazzo);	//estrae una carta scoperta per il server

	while(ingioco<=players)		//inizia a giocare col "ingioco"
		{
		rd=write(fd[ingioco],"play^",5);	//comunica al giocatore che e' il suo turno
		if (rd<0) {perror("write");return 0;}
		rd=read(fd[ingioco],buff,20);
		if (rd<0) {perror("read");return 0;}

		if (strncmp(buff,"ready^",6)==0)	// inizio gioco
			{
			set_msg(msg,carta_server->val,carta_server->seme);	//pacchetto contenente la carta scoperta del server
			rd=write(fd[ingioco],msg,strlen(msg));		//invia al giocatore ingioco la carta del server
			if (rd<0) {perror("write");return 0;}
			}

		bet[ingioco]=5;
		punteggio[ingioco]=0;
		*assi=0;
		strcpy(msg,"busy ");// crea il messaggio di attesa per tutti gli altri giocatori
		strcat(msg,utenti[ingioco]);
		strcat(msg,"^");
		inviamsg_mod(players,fd,ingioco,msg,strlen(msg));	//comunica ai rimanenti client di chi e' il turno
		
		while(1)
			{
			memset(&buff,0,sizeof(buff));
			rd=read(fd[ingioco],buff,20);
			if (rd<0) {perror("read");return 0;}

			if (strncmp(buff,"get^",4)==0)
				{
				carta_tmp=get_carta(mazzo);			//prendi carta
				set_msg(msg,carta_tmp->val,carta_tmp->seme);	//crea pacchetto da inviare ai giocatori
				inviamsg(players,fd,msg,strlen(msg));
				read(fd[ingioco],buff,3);
				punteggio[ingioco]=calcola_punteggio(fd[ingioco],carta_tmp->val,punteggio[ingioco],assi);
				if (punteggio[ingioco]==-1){break;}		
				}

			if (strncmp(buff,"stop^",5)==0){break;}	//usciamo dal ciclo "turno" del giocatore ingioco

			if (strncmp(buff,"esci^",5)==0){
				uscite[ingioco]=1;
				break;}

			if (strncmp(buff,"raise",5)==0)		//il giocatore vuole rilanciare
				{
				tmp2=strtok(buff," ");
				tmp2=strtok(NULL,"^");
				bet[ingioco]=bet[ingioco]+atoi(tmp2);		//sommiamo la puntata

				if ((fiches[ingioco]-bet[ingioco])<0)		//se non ci sono fiches
					{
					bet[ingioco]=bet[ingioco]-atoi(tmp2);	//ripristiniamo
					rd=write(fd[ingioco],"miss^",5);	//e informiamo il client
					if (rd<0) {perror("write");return 0;}
					}
				else 
					{
					rd=write(fd[ingioco],"ok^",3);
					if (rd<0) {perror("write");return 0;}
					}					
				}
			}

		pthread_mutex_lock(&mut);
		players=numplayers;		//ad ogni turno aggiorniamo il numero di giocatori in gara
		pthread_mutex_unlock(&mut);
		ingioco++;
		}

	punteggio[0]=play_banco(fd,players,carta_server,mazzo);
	invia_risultato(fd,punteggio,bet,players,fiches);

	i=1;
	
	while (i<=players)				     //controlla tutti i giocatori
		{
		if (flag==1)					//se il tempo è scaduto
			{
			strcpy(buff,"temposcaduto^");		  //vengono cacciati dal tavolo
			rd=write(fd[i],buff,strlen(buff));	
			if (rd<0) {perror("write");return 0;}
			pthread_mutex_lock(&mut);
			close(fd[i]);
			fd[i]=fd[players];                        //swap giocatore I con l'ULTIMO
			fiches[i]=fiches[players];		    //swap giocatore I con l'ULTIMO
			strcpy(utenti[i],utenti[players]);         //swap giocatore I con l'ULTIMO
			numplayers--;
			players=numplayers;
			pthread_mutex_unlock(&mut);
			}
		else
			{
			if (uscite[i]==1)				//se hai scelto di uscire
				{
				strcpy(buff,"seiuscito^");		  //vai via
				rd=write(fd[i],buff,strlen(buff));	
				if (rd<0) {perror("write");return 0;}
				uscite[i]=0;
				pthread_mutex_lock(&mut);
				close(fd[i]);
				fd[i]=fd[players];                        //swap giocatore I con l'ULTIMO
				fiches[i]=fiches[players];		    //swap giocatore I con l'ULTIMO
				strcpy(utenti[i],utenti[players]);         //swap giocatore I con l'ULTIMO
				numplayers--;
				players=numplayers;
				pthread_mutex_unlock(&mut);
				}

			if (fiches[i]<5)			  // se hanno meno di 5 fisches
				{
				strcpy(buff,"gameover^");		  //vengono cacciati dal tavolo
				rd=write(fd[i],buff,strlen(buff));	
				if (rd<0) {perror("write");return 0;}
				pthread_mutex_lock(&mut);
				close(fd[i]);
				fd[i]=fd[players];                        //swap giocatore I con l'ULTIMO
				fiches[i]=fiches[players];		    //swap giocatore I con l'ULTIMO
				strcpy(utenti[i],utenti[players]);         //swap giocatore I con l'ULTIMO
				numplayers--;
				players=numplayers;
				pthread_mutex_unlock(&mut);
				}
			}
		i++;
		}

	if (test_numcarte(mazzo)==0) 		//se abbiamo meno di 52 carte nel mazzo
		{
		mazzo=init_mazzo(mazzo);
		inviamsg(players,fd,"remixed^",8);			//mischiamo e informiamo i client dell'accaduto

		for(i=1;i<=players;i++)
			{
			rd=read(fd[i],buff,3);
			if (rd<0) {perror("read");return;}
			}
		}

	if (players==0)  //se i giocatori finiscono anche il banco chiude
		{
		close(fd[0]);
		break;
		}
	}

inviamsg(players,fd,"gameover^",9); //fine del gioco per tutti 			
time(&ora);
ctime_r(&ora,buff);
rd=write(fdlog,buff,strlen(buff));   //orario di fine gioco per il log
if (rd<0) {perror("write");return 0;}
close(fdlog);		// chiusura log
close(fd[0]); 
}


Avatar utente
clynamen
Prode Principiante
Messaggi: 41
Iscrizione: sabato 6 novembre 2010, 19:21

Re: Errore di segmentazione (core dump creato) please help m

Messaggio da clynamen »

Hai provato a trovare l'errore con gdb?
Scrivi risposta

Ritorna a “Programmazione”

Chi c’è in linea

Visualizzano questa sezione: 0 utenti iscritti e 5 ospiti