Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
C/C++ - allocazione dinamica delle strutture
Forum - C/C++ - allocazione dinamica delle strutture

Avatar
Franciu (Normal User)
Newbie


Messaggi: 3
Iscritto: 09/09/2009

Segnala al moderatore
Postato alle 12:29
Mercoledì, 09/09/2009
Ciao! sono nuova di queste parti e volevo sottoporvi un problema: come si deve fare per allocare le strutture utilizzando la malloc nel linguaggio C? In molti programmi che ho provato a scrivere le ho allocate in un certo modo e mi compila senza problemi, ma quando faccio per eseguire mi esce l'errore di Segmentation fault. Qui di seguito vi riporto un codice nel quale riscontro questo problema. Avrei bisogno urgentemente di una risposta, tra pochi giorni ho l'esame di programmazione e se riuscissi a risolvere questo problema sarebbe meglio! Vi ringrazio già in anticipo per l'aiuto!!:)

Codice sorgente - presumibilmente C++

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4.  
  5. struct squadra {
  6.         char* nome;
  7.         int pv, ppe, pp, gf, gs;
  8. };
  9.  
  10. struct risultato {
  11.         char* nome;
  12.         int pg, p;
  13.         float mgf, mgs;
  14. };
  15.  
  16. int partiteg(struct squadra s){
  17.         int n;
  18.         n = s.pv + s.ppe + s.pp;
  19.         return n;
  20. }
  21.  
  22. int punteggio(struct squadra s){
  23.         int n;
  24.         n = s.pv * 3 + s.pp;
  25.         return n;
  26. }
  27.  
  28. int main(int argc, char** argv){
  29.         if(argc<3){
  30.                 printf("Non sono stati forniti tutti i nomi dei file\n");
  31.         }
  32.         FILE* f = fopen(argv[1], "r");
  33.         int n;
  34.         fscanf(f, "%d", &n);
  35.         //ecco l'allocazione incriminata:
  36.         struct squadra* squadre = (struct squadra*)malloc(sizeof(struct squadra)*n);
  37.         int i;
  38.         for(i=0; i<n && !feof(f); i++){
  39.                 fscanf(f,"%s %d %d %d %d %d",squadre[i].nome,&squadre[i].pv,&squadre[i].ppe,&squadre[i].pp,&squadre[i].gf,&squadre[i].gs);
  40.                 printf("%s %d %d %d %d %d",squadre[i].nome,squadre[i].pv,squadre[i].ppe,squadre[i].pp,squadre[i].gf,squadre[i].gs);
  41.         }
  42.         fclose(f);
  43.  
  44.  
  45.         FILE* r = fopen(argv[2], "w");
  46.         //e qui c'è l'altra
  47.         struct risultato* risultati = (struct risultato*) malloc(sizeof(struct risultato)*n);
  48.         for(i=0; i<n; i++){
  49.                 strcpy(risultati[i].nome, squadre[i].nome);
  50.                 risultati[i].pg = partiteg(squadre[i]);
  51.                 risultati[i].p = punteggio(squadre[i]);
  52.                 risultati[i].mgf = risultati[i].pg / squadre[i].gf;
  53.                 risultati[i].mgs = risultati[i].pg / squadre[i].gs;
  54.                 fprintf(r, "%s %d %d %f %f", risultati[i].nome, risultati[i].pg, risultati[i].p, risultati[i].mgf, risultati[i].mgs);
  55.         }
  56.         fclose(r);*/
  57.         free(squadre);
  58.         free(risultati);
  59.         return 0;
  60. }



PM Quote
Avatar
vince92 (Normal User)
Rookie


Messaggi: 29
Iscritto: 18/11/2008

Segnala al moderatore
Postato alle 15:19
Mercoledì, 09/09/2009
Puoi scrivere il testo del problema che risolve il programma in C che hai postato?

A mio modesto parere, una malloc non provoca un segment fault, ma viene provocata da altre cose (tra l'altro mi sembra che l'allocazione della struttura sia fatta correttamente). La malloc al limite ti restituisce un puntatore NULL.

Mi permetto di segnalarti due "errori" che ho visto dando uno sguardo velocemente al tuo programma.

1) In C TUTTE le variabili devono essere dichiarate all'inizio e non come fai tu che le dichiari al volo

2) Tieni presente che quando dividi due int ottieni un int, non un float come forse tu immagini, visto che hai assegnato il risultato di una divisione tra due int ad un float. Per ottenere un float devi fare il cast di almeno uno dei due operandi

Ultima modifica effettuata da vince92 il 09/09/2009 alle 15:21
PM Quote
Avatar
Franciu (Normal User)
Newbie


Messaggi: 3
Iscritto: 09/09/2009

Segnala al moderatore
Postato alle 15:49
Mercoledì, 09/09/2009
Grazie dei consigli. Ti scrivo il testo:

Si consideri un file contenente informazioni relative ai risultati delle partite di calcio di un girone (max 18 squadre). Il file contiene in ciascuna riga, separati da spazio: noem della squadra(max 10 caratteri), numero di partire vinte, numero di partire perse, numero di partire pareggiate. goal fatti, goal subiti. Si scriva un programma che definita un'opportuna struttura dati, carichi in memoria questi dati e generi un secondo file che contiene in ciascuna riga le seguenti informazioni: nome squadra, numero partire giocate, punteggio(3 punti per partita vinta e 1 per partita pareggiata), media dei goal fatti per partita, media dei goal subiti per partita.

PM Quote
Avatar
vince92 (Normal User)
Rookie


Messaggi: 29
Iscritto: 18/11/2008

Segnala al moderatore
Postato alle 16:54
Mercoledì, 09/09/2009
Bene, allora...

Innanzitutto dovresti prendere in input un file nella seguente forma:

milan 10 2 1 50 3
juve 3 2 1 22 4
inter 15 3 2 19 4

quindi non capisco il tuo fscanf(f, "%d", &n);(immagino che cercavi di leggere il numero delle squadre, ma nel file non è presente e come prima informazione trovi una stringa, non un valore numerico intero.

Sinceramente non ho controllato il resto, ma già quell'fscanf è sbagliato.
Dovresti leggere man mano i valori ed ad ogni nuova riga allochi una nuova struttura(magari con un realloc).

Ti posto un esempio, se c'è qualcosa che non capisci dimmelo

Codice sorgente - presumibilmente C++

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. #define dmax 11
  6.  
  7.  
  8. typedef struct squadra{
  9.         char nome[dmax];
  10.         int numVinte;
  11.         int numPerse;
  12.         int numPareggiate;
  13.         int golFatti;
  14.         int golSubiti;
  15. }squadra;
  16.  
  17. typedef struct risultato{
  18.         char nome[dmax];
  19.         int partiteGiocate;
  20.         int punteggio;
  21.         float mediaGoalFatti;
  22.         float mediaGoalSubiti;
  23. }risultato;
  24.  
  25. int main(){
  26.         char *input="input.txt",*output="output.txt";
  27.         FILE *in,*out;
  28.         squadra *squadre = NULL;
  29.         risultato *risultati=NULL;
  30.         int i=0,n=0;
  31.         in = fopen(input,"r");
  32.         if(in==NULL)
  33.                 printf("Errore durante l'apertura del file di input\n");
  34.         else
  35.         {
  36.                 while(!feof(in))
  37.                 {
  38.                         n++;
  39.                         squadre = (squadra *)realloc(squadre,sizeof(squadra)*n);
  40.                         fscanf(in,"%s %d %d %d %d %d",(squadre[i].nome),&(squadre[i].numVinte),&(squadre[i].numPerse),&(squadre[i].numPareggiate),&(squadre[i].golFatti),&(squadre[i].golSubiti));
  41.                         i++;
  42.                 }
  43.  
  44.                 i=0;
  45.                 risultati = (risultato*)calloc(n,sizeof(risultato));
  46.  
  47.                 for(i=0;i<n;i++)
  48.                 {
  49.                         strcpy(risultati[i].nome,squadre[i].nome);
  50.  
  51.                         risultati[i].partiteGiocate = squadre[i].numVinte + squadre[i].numPerse + squadre[i].numPareggiate;
  52.  
  53.                         risultati[i].mediaGoalFatti = (float) squadre[i].golFatti / risultati[i].partiteGiocate;
  54.  
  55.                         risultati[i].punteggio = squadre[i].numVinte * 3 + squadre[i].numPareggiate;
  56.  
  57.                         risultati[i].mediaGoalSubiti = (float) squadre[i].golSubiti / risultati[i].partiteGiocate;
  58.                 }
  59.  
  60.                 fclose(in);
  61.                 free(squadre);
  62.  
  63.                 out = fopen(output,"w");
  64.  
  65.                 for(i=0;i<n;i++)
  66.                 {
  67.                         fprintf(out,"%s %d %d %f %f\n",risultati[i].nome,risultati[i].partiteGiocate,risultati[i].punteggio,risultati[i].mediaGoalFatti,risultati[i].mediaGoalSubiti);
  68.                 }
  69.  
  70.                 fclose(out);
  71.                 free(risultati);
  72.         }
  73.         return 0;
  74. }


PM Quote
Avatar
Franciu (Normal User)
Newbie


Messaggi: 3
Iscritto: 09/09/2009

Segnala al moderatore
Postato alle 10:10
Giovedì, 10/09/2009
Ok grazie, il codice mi è chiaro. Avevo messo quella fscanf per leggere il numero di squadre presenti nel file, che ovviamente avrei aggiunto io dato che non era richiesto dal testo, e poi avrei allocato tot strutture in base al numero letto dalla prima riga. Comunque è tutto chiaro, grazie mille!

PM Quote