Problema segmentation fault .c

di il
29 risposte

29 Risposte - Pagina 2

  • Re: Problema segmentation fault .c

    Giusto, giusto! ok grazie ora funzica
  • Re: Problema segmentation fault .c

    Ho un altro problema, sta volta con il salvataggio o la lettura da file
    
    
    salvalista(&DispoPtr); //chiamata in main
    
    .
    .
    .
    
    void salvalista (TipoDispositivo **Dispo) { //*&Device
    
    FILE *ListDevPtr;
    TipoDispositivo *currentPtr;
    TipoDispositivo *current2Ptr;
    
    current2Ptr=malloc(sizeof(TipoDispositivo));
    
      if (( ListDevPtr = fopen("ListaDispositivi.dat", "wb")) == NULL){
      	 printf("Il file non può essere aperto");
           }
    	 else{
              currentPtr=*Dispo;
              if (currentPtr !=NULL){
                    while(currentPtr!=NULL){
                    fwrite(&currentPtr,sizeof(TipoDispositivo),1,ListDevPtr); 
                    fread(&current2Ptr,sizeof(TipoDispositivo),1,ListDevPtr); 
                    printf("Dispositivo Salvato: %s\n", current2Ptr->nome);  
                    currentPtr=(*currentPtr).nextPtr;
                 }
                 printf("Salvato");
              }
              else{
                   printf("Lista Dispositivi vuota, impossibile salvare l'elenco dei dispositivi\n");
                   return;
                   }
                 fclose(ListDevPtr);
         }
    }
    Al Momento della fread mi viene fuori il nostro amico errore di segmentazioni.
    Non riesco però a capire se l'errore proviene da un errore nella fwrite (nel senso che non scrive nel file o scrive in modo errato) oppure appunto nella fread (che ho messo li apposta per capire se leggendo dal file dava problemi).
  • Re: Problema segmentation fault .c

    Scusa ma tu salvi su disco ogni struttura compresi i valori dei puntatori?
  • Re: Problema segmentation fault .c

    A quali puntatori ti riferisci? a quelli interni alla struttura si, altrimenti nella funzione (che non ho pubblicato ma a cui sto lavorando) che carica i dati da file non avrei l'indirizzo della struttura successiva.
  • Re: Problema segmentation fault .c

    No ... è un errore grave.

    I valori dei puntatori non puoi rileggerli da disco e assegnarli perché non saranno validi ...
  • Re: Problema segmentation fault .c

    Ah ok, quindi quando ricarico ogni struttura devo assegnarle un nuovo puntatore e riassegnare un valore a nextPtr giusto? magari inizializzandolo prima a null e poi assegnandogli l'indirizzo del nodo successivo.
  • Re: Problema segmentation fault .c

    Emanuele90 ha scritto:


    Ah ok, quindi quando ricarico ogni struttura devo assegnarle un nuovo puntatore e riassegnare un valore a nextPtr giusto? magari inizializzandolo prima a null e poi assegnandogli l'indirizzo del nodo successivo.
    Quando scrivi, devi solamente considerare i dati dei vari nodi, senza i puntatori.

    Quando rileggi, devi considerare i dati come se ti arrivassero per la prima volta, quindi devi creare il nuovo nodo (allocando la memoria) e utilizzare il nuovo puntatore per collegare il nxtPtr.
  • Re: Problema segmentation fault .c

    Ok ma con la fwrite come gli dico di scrivere tutti i dati senza i puntatori? altrimenti devo fare un salvataggio formattato con fprintf ma perderei l'impostazione a struttura senza contare che non so se sia possibile leggere il dati in modo casuale da un file sequenziale.

    la funzione di lettura è questa e penso che più o meno faccia quello che consigli (devo ancora testarla e finirla, cosa che non posso fare se non mi salva le cose correttamente).
    void caricalista (TipoDispositivo **Dispo) { //*&Device
    
    void coda (TipoDispositivo **);
    
    FILE *ListDevPtr;
    TipoDispositivo *currentPtr;
    
      if (( ListDevPtr = fopen("ListaDispositivi.dat", "rb")) == NULL){
      	 printf("Il file non può essere aperto");
           }
      else{
          currentPtr=*Dispo;
          while(!feof(ListDevPtr)){
                fread(&currentPtr,sizeof(TipoDispositivo),1,ListDevPtr); 
                printf("Nome %s",currentPtr->nome); 
                coda(&currentPtr);
                currentPtr=(*currentPtr).nextPtr;
               }
          if (currentPtr == NULL) {
             printf("Lista Dispositivi vuota, impossibile caricare l'elenco dei dispositivi\n");
             return;
          }
          else {
               printf("Lista Caricata");
               }
           }
          fclose(ListDevPtr);
    }
    
    //------------------------------------------------------//
    
    void coda (TipoDispositivo **DevicePtr) {
         
    TipoDispositivo *newDevicePtr;
    
    newDevicePtr = malloc(sizeof(TipoDispositivo));
    
    if( newDevicePtr !=NULL) {
        newDevicePtr = *DevicePtr;
        }
    }
    
  • Re: Problema segmentation fault .c

    Puoi anche scrivere i puntatori (per semplificare la scrittura) ma quando rileggi i dati devi ignorare i valori dei puntatori e riallocare i nodi.
  • Re: Problema segmentation fault .c

    Quindi cosa faccio, creo un'altra struttura alternativa, dove chiamo nextPtr in un altro modo per evitare la corrispondenza dei nomi, in cui salvo i dati che mi ritornano dal file?
  • Re: Problema segmentation fault .c

    No no ... va bene scrivere e leggere nella struttura ma quando rileggi devi considerare tutti i puntatori come non validi e riscriverli dopo aver allocato nuovamente la memoria.
  • Re: Problema segmentation fault .c

    Uhm ok
  • Re: Problema segmentation fault .c

    Allora li ridichiaro semplicemente NULL una volta riletti
  • Re: Problema segmentation fault .c

    Ho modificato il codice nel modo seguente
    //------------------------------------------------------//
    
    void caricalista (TipoDispositivo **Dispo) { //*&Device
    
    void coda (TipoDispositivo **);
    
    FILE *ListDevPtr;
    TipoDispositivo *currentPtr;
    *Dispo=NULL;
    
      if (( ListDevPtr = fopen("ListaDispositivi.dat", "rb")) == NULL){
      	 printf("Il file non può essere aperto");
           }
      else{
          currentPtr=*Dispo;
          while(!feof(ListDevPtr)){
                if(fread(&currentPtr,sizeof(TipoDispositivo),1,ListDevPtr)){ 
                printf("Nome %s\n",currentPtr->nome); 
                coda(&currentPtr);
                currentPtr=(*currentPtr).nextPtr;
                printf("Lista Caricata");
               }
         else {
              printf("Lista Non Caricata");
              }
           }
          fclose(ListDevPtr);
    }
    }
    
    //------------------------------------------------------//
    
    void coda (TipoDispositivo **DevicePtr) {
         
    TipoDispositivo *newDevicePtr;
    TipoDispositivo *tailDevicePtr=malloc(sizeof(TipoDispositivo));
    
    newDevicePtr = malloc(sizeof(TipoDispositivo));
    
    if( newDevicePtr !=NULL) {
        newDevicePtr = *DevicePtr;
        newDevicePtr->nextPtr=NULL;
        }
        
        (*tailDevicePtr).nextPtr=newDevicePtr;
        tailDevicePtr=newDevicePtr;
    }
    
    Premetto che uso l'espressione *Dispo=NULL; per assicurarmi che il puntatore al primo nodo sia effettivamente nullo e che quindi i dati possano provenire solamente dal file.
    Se creo un dispositivo nella stessa sessione nella quale lo salvo e poi carico da file le informazioni vengono caricate ma se chiedo di stampare a video la lista dispositivi mi viene detto che è vuota.
    Sono sicuro che il Dispositivo viene caricato perchè il mio fedele printf mi stampa sempre il nome del dispositivo.

    Se invece creo la lista e la salvo in una sessione precedente e poi tento di caricarla mi da errore.
  • Re: Problema segmentation fault .c

    Scusa ma cosa ci fa

    void coda (TipoDispositivo **);

    dentro la funzione caricalista ?

    E soprattutto dove fai le malloc per allocare lo spazio per quello che leggi? Ovvero la malloc va fatta prima di passare il relativo puntatore alla fread.

    Se leggi i dati dal disco, ti ricordo che la lista precedente va liberata tutta e va riallocata durante la lettura. Forse non sono stato chiaro ... Lo schema di massima dell'operazione di caricamento deve essere

    1) libero la memoria dei nodi eventualmente presenti in lista

    2) alloco la memoria per un elemento

    3) leggo dal file il prossimo elemento nella memoria allocata

    4) aggiungo il nodo appena letto alla lista aggiornando i vari puntatori

    5) continuo al passo 2 se il file non è finito
Devi accedere o registrarti per scrivere nel forum
29 risposte