Errore di segmentazione

di il
6 risposte

Errore di segmentazione

Come da titolo ho un errore di segmentazione nel programma ma non ho capito perchè e come risolverlo.


// esercizio 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void apri(char *str,FILE *fd);
char *cercaPrimo(FILE *fd);

int main(int argc,char *argv[]){
	if (argc==3){
		FILE *fd;
		fd=malloc(sizeof(FILE));
		apri(argv[1],fd);
		printf("1 \n");
		char *primo; 
		primo=cercaPrimo(fd);
		printf("stringa: %s\n",primo);
		
	}
	
	return 0;
}

void apri(char *str,FILE *fd){

	fd= fopen(str, "r");
	if (fd==NULL){
		printf("errore...");
		exit(EXIT_FAILURE);
	}
}

char *cercaPrimo(FILE *fd){
	char *primo;
	primo=malloc(sizeof(char));
	printf("2 \n");
	while (!feof(fd)){	
		printf("1 \n");
		fgets(primo,25,fd);
		printf("stringa: %s\n",primo);
	}
	return primo;
}

il programma non è completo perchè cerco di fare parti di codice e compilare volta per volta. in pratica fino ad adesso il programma dovrebbe aprire il file dato da linea comandi e leggere tutte le righe del file e metterle ciclicamente in una variabile.
l'errore è probabilmente nel while della funzione cercaPrimo. se riuscite date anche una spiegazione generica su come evitare questo errore perchè purtroppo mi capita spesso
Inoltre se invece di dividere il programma in funzioni metto tutto nel main funziona tutto, perchè?

6 Risposte

  • Re: Errore di segmentazione

    Ovvio! Straovvio!

    Ragiona!

    Errore concettuale: che cosa ritorna la fopen?
    E il suo risultato, come si usa?
    Che cosa vuol dire passare un parametro per valore e non per reference?

    Dalle domande, arrivi all'errore!
  • Re: Errore di segmentazione

    migliorabile ha scritto:


    Ovvio! Straovvio!

    Ragiona!

    Errore concettuale: che cosa ritorna la fopen?
    E il suo risultato, come si usa?
    Che cosa vuol dire passare un parametro per valore e non per reference?

    Dalle domande, arrivi all'errore!
    la fopen dovrebbe ritornare il puntatore al file aperto (se ha successo).
    da quello che ho visto alla maggior parte delle funzione va passato l'indirizzo del file (quindi per reference).
    se passi un parametro per valore passi appunto solo il valore e generalmente non viene modificato dalla funzione, per reference vuol dire passare l'indirizzo e in questo caso il valore del parametro risulterà modificato alla fine della funzione.
    Giusto?

    per me continua a non essere molto ovvio l'errore
  • Re: Errore di segmentazione

    Questa riga

    fd=malloc(sizeof(FILE));

    non ha senso.

    La fopen restituisce il puntatore ad una struttura FILE già allocata.
    Se vuoi che la funzione apri restituisca questo puntatore, devi passarlo come puntatore doppio.
  • Re: Errore di segmentazione

    Grazie mille! risolto
  • Re: Errore di segmentazione

    Posta la soluzione per gli utenti ...
  • Re: Errore di segmentazione

    La correzione del problema è qusta:
    
    // esercizio minuti lavorati (9.1)
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    void apri(char *str,FILE **fd);
    void cercaPrimo(FILE **fd,char *primo,char *code);
    void cercaUltimo(FILE **fd,char *ultimo,char *code);
    int strContain(char *primo,char *code);
    int minuti(char *primo);
    
    int main(int argc,char *argv[]){
    	if (argc==3){
    		FILE **fd;
    		fd=malloc(sizeof(FILE));
    		apri(argv[1],fd);
    		char *primo;
    		char *code;
    		code=argv[2];
    		primo=malloc(sizeof(char));
    		cercaPrimo(fd,primo,code);
    		printf("primo: %s\n",primo);
    		char *ultimo;
    		ultimo=malloc(sizeof(char));
    		cercaUltimo(fd,ultimo,code);
    		printf("ultimo: %s\n",ultimo);
    		int min1,min2;
    		min1=minuti(primo);
    		printf("%d\n",min1);
    		min2=minuti(ultimo);
    		printf("%d\n",min2);
    		int risultato;
    		risultato=min2-min1;
    		printf("risultato è: %d \n",risultato);
    		
    	}
    	
    	return 0;
    }
    
    void apri(char *str,FILE **fd){
    
    	*fd= fopen(str, "r");
    	if (fd==NULL){
    		printf("errore...");
    		exit(EXIT_FAILURE);
    	}
    }
    
    void cercaPrimo(FILE **fd,char *primo,char *code){
    	int ris;
    	while (!(feof(*fd))){	
    			primo=fgets(primo,25,*fd);
    			ris=strContain(primo,code);;
    			if (ris==1){
    				break;
    			}
    					
    	}
    }
    
    void cercaUltimo(FILE **fd,char *ultimo,char *code){
    	int ris;
    	char *p;
    	p=malloc(sizeof(char));
    	while (!(feof(*fd))){	
    		p=fgets(p,25,*fd);
    		if (p==NULL){
    			break;
    		}
    		ris=strContain(p,code);
    		if (ris==1){
    			strcpy(ultimo,p);
    		}
    	}
    }
    
    int strContain(char *primo,char *code){
    	int len1=strlen(primo);
    	int len2=strlen(code);
    	int i,count;
    	count=0;
    	for (i=0;i<len1;i++){
    		if (primo[i]==code[count]){
    			count++;
    		}else{
    			count=0;
    		}
    		if (count==(len2)){;
    			return 1;
    		}
    	}
    	return 0;
    }
    
    int minuti(char *primo){
    	int ore,minuti;
    	char *p;
    	ore=strtol(primo,&p,0);
    	minuti=strtol(p,&p,0);
    	printf("%d\n",ore);
    	printf("%d\n",minuti);
    	return (ore*60+minuti);
    }
    
    questa è la funzione completa in quanto quella postato all'inizio era solo la parte iniziale di un problema più generale.
    La correzione è stata (come detto da oregon) passare alla funzione apri un doppio puntatore a fd.
Devi accedere o registrarti per scrivere nel forum
6 risposte