Newsgroup: it.comp.os.linux.development
Titolo: Segmentation fault... del programma (e del sottoscritto)

Vi allego il sorgente del mio programma sperando qualche anima pia
possa darmi una mano (sono anni che non programmo in c  e onestamente
sono in difficoltà)
Il programma viene compilato ma va in segmentation fault.
Immagino che il problema sorga nel ciclo di creazione dei clienti (ho
testato tutto il resto e funzionava), ma non riesco nè a trovare una
soluzione più elegante, nè a trovare una soluzione funzionante.
Ringrazio anticipatamente chi mi aiuterà.
Saluti.
#define NUM_BARBIERI_DEFAULT 3
sem_t customerIsWaiting;
sem_t accessToWaitingRoom;
sem_t doneHairCut;
int allDone = 0;
int numCustomerWaiting = 0;
int numCustomers = 10;
int numChairs = 5;
struct param_barbieri{
	char nome;
	/*Volendo passare degli altri parametri basterebbe aggiungere dei
campi qui*/
	};
struct param_clienti{
	int numero;
	/*Volendo passare degli altri parametri basterebbe aggiungere dei
campi qui*/
	};
void *thread_func_cliente(void* dummy) {
	for(;;) {
		struct param_clienti *cliente = (struct param_clienti*)dummy;
		printf("Il cliente %d arriva nel negozio dei barbieri.\n",
cliente->numero);
		sem_wait(&accessToWaitingRoom);
		if (numCustomerWaiting < numChairs) {
			printf("Il cliente %d entra nella sala d'attesa.\n",
cliente->numero);
			numCustomerWaiting++;
			sem_post(&customerIsWaiting);
			sem_post(&accessToWaitingRoom);
			sem_wait(&doneHairCut);
			printf("Il cliente %d è stato servito ed esce dal negozio.\n",
cliente->numero);
			return;
		} else {
			sem_post(&accessToWaitingRoom);
			printf("Il cliente %d esce dal negozio dei barbieri perchè il
negozio è pieno.\n", cliente->numero);
			sleep(5); //retry after 5 sec
		}
	}
}
void *thread_func_barbiere(void *dummy) {
	for(;;) {
		struct param_barbieri *barbiere = (struct param_barbieri*)dummy;
		printf("Il Barbiere %c dorme beatamente.\n",barbiere->nome);
		sem_wait(&customerIsWaiting);
		if (allDone)
			break;
		sem_wait(&accessToWaitingRoom);
		printf("Il Barbiere %c si sveglia.\n",barbiere->nome);
		numCustomerWaiting--;
		sem_post(&accessToWaitingRoom);
		printf("Il Barbiere %c inizia il taglio (speriamo non
sbagli).\n",barbiere->nome);
		sleep(1);
		sem_post(&doneHairCut);
		printf("Il Barbiere %c ha finito il taglio (tutto
bene).\n",barbiere->nome);
	}
}
int main(int argc, char *argv[]) {
	unsigned numBarbieri = 0;
	pthread_t *btid;
	pthread_t *ctid[0];
	struct param_clienti *clienti[0];
	char nome = 'a';
	int i=0;
	int j=0;
	/*
	STEP 1: Inserimento del numero di barbieri
	Se l'utente inserisce per sbaglio un valore non corretto (es: una
lettera o un segno d'interpunzione) il numero di barbieri viene fissato
a NUM_BARBIERI_DEFAULT (questo perchè la scanf converte tutti i valori
non numerici a zero)
	*/
	printf("Inserisci il numero di Barbieri:");
	scanf("%d",&numBarbieri);
	printf("-------------------------------------\n");
	if (numBarbieri == 0){
		numBarbieri = NUM_BARBIERI_DEFAULT;
		printf("Il numero inserito non è valido; pertanto di default vengono
inseriti %d barbieri\n",numBarbieri);
	} else printf ("Barbieri presenti: %d\n", numBarbieri);
	/*
	STEP 2: Creazione dei thread dei barbieri
	*/
	struct param_barbieri barbieri[numBarbieri];
	btid = (pthread_t*)calloc(numBarbieri,sizeof(pthread_t));
	if (btid ==NULL){
	printf("Allocazione non riuscita");
	exit(1);
	}
	for (i=0;i<numBarbieri;i++){
		barbieri[i].nome =nome;
		pthread_create(&btid[i], NULL, &thread_func_barbiere,&(barbieri[i]));
		nome++;
	};
	/*
	STEP 3: Creazione dei thread dei clienti
	*/
	for (;;){
		ctid[j]=(pthread_t*)calloc(1,sizeof(pthread_t));
		clienti[j]=(struct param_clienti *)calloc(1,sizeof(struct
param_clienti));
		clienti[j]->numero = j;
		pthread_create(ctid[j], NULL, &thread_func_cliente, &(clienti[j]));
		j++;
	};
	return(0);
}

    clienti[j]=(struct param_clienti *)calloc(1,sizeof(struct
Qui li tratti come se avessero dimensioni > j.
Max

Max M. ha scritto:

Scusa se ti chiedo una banalità, ma come posso correggere la cosa?

	};
Da questo ciclo non esci mai (btw perché non usi la forma "umana" 
for (j=qualcosa; condizione; j++) ?)

ovviamente grazie per l'aiuto....

Con zero che speri di ottenere?
In realtà volevo solo effettuare una dichiarazione ed allocare
dinamicamente la memoria necessaria... ma siccome sono
"arruginitissimo" (non lavoro con puntatori da almeno 5-6 anni) non mi
è più chiaro ed immediato quale sia la forma corretta di lavorare. Se
mi aiutate mi fate veramente un gran favore....

dinamicamente la memoria necessaria... 
allora puoi scrivere tranquillamente:
   pthread_t *ctid;
   struct param_clienti *clienti;
Ricordati ovviamente di allora memoria per il numero di phtread_t e
struct param_clienti necessari.

Andrea Laforgia ha scritto:

Siccome il numero di pthread non mi è noto (vengono generati "in
maniera infinita") devo fare una malloc per ogni passaggio del ciclo
for(;;); come faccio però a distinguere i vari elementi allocati; in
questo caso la notazione ctid[j] (o clienti[j]) è corretta?
Grazie ancora per la disponibilità.

questo caso la notazione ctid[j] (o clienti[j]) č corretta?
Sě.