Visualizzazione dei risultati da 1 a 6 su 6
  1. #1

    C- problema struttura dati per le liste

    Salve a tutti, avrei un problema con questo codice .

    struct list{
    int dato;
    struct list*next;
    };

    int main(){
    int i,n;
    struct list primo;
    primo.next=NULL;
    struct list* tmp;
    *tmp=primo;
    scanf(" %d ", &n);
    for(i=0;i<n-1;i++){
    printf(" %d ", i);
    tmp->next=(struct list*)malloc(sizeof(struct list));
    tmp=tmp->next;
    }

    tmp->next=NULL;
    *tmp=primo;
    while(tmp->next!=NULL){
    scanf(" %d ", &(tmp->dato));
    tmp=tmp->next;
    }

    *tmp=primo;
    while(tmp->next!=NULL)
    printf(" %d ", tmp->dato);
    return 0;
    }

    non capisco perchè ma viene compilato, ma una volta che viene lanciato immetto un valore ( che dovrebbe essere n ) poi un altro valore e mi da segmentation fault.

    Per capire dove fosse l'errore dapprima ho messo come nota tutto il ciclo dove si inseriscono i dati e quello che li stampa, ma ancora mi dava segmentation fault,

    poi ho provato a inserire un dato solo nel primo elemento dopo che la lista intera era stata creata
    e anche in questo caso mi dava segmentation fault,

    ho capito quindi che la lista non veniva creata,

    Il punto è che se la lista non viene creata perchè mi fa inserire due valori quando lancio il programma?
    a norma dovrebbe farmi inserire solo la scanf che inserisce il valore in n (numero degli elementi della lista);

    quindi ho provato una cosa che ha dato dei risultati inquietanti:
    ho messo come nota tutta la parte del testo dopo lo scanf che prende il valore di n
    e ho messo una printf che mi stampi il valore di n
    anche in questo caso mi fa inserire due valori e mi saluta con un segmentation fault, non capisco perchè.
    come mi può chiedere due volte di dargli degli input se ho messo solo una scanf!!

  2. #2
    Utente di HTML.it
    Registrato dal
    Jul 2008
    Messaggi
    1,326
    Ciao Clavulcar, ti consiglio innanzitutto di postare meglio il codice la prossima volta perché così non si capisce nulla (oltre al fatto che il regolamento prevede che il codice vada scritto utilizzando i tag appositi).

    Te lo riposto io così cerchiamo di capirci qualcosa meglio:

    codice:
    #include <stdio.h>
    #include <stdlib.h>
    
    struct list{
       int dato;
       struct list*next;
    };
    
    int main(void)
    {
       int i,n;
    
       struct list primo;
    
       primo.next = NULL;
    
       struct list* tmp;
    
       *tmp = primo;
    
       scanf(" %d ", &n);
    
       for ( i = 0; i < n-1; i++ ) {
       
          printf(" %d ", i);
          tmp -> next = (struct list*) malloc( sizeof(struct list) );
          tmp = tmp -> next;
       }
    
       tmp -> next = NULL;
       *tmp = primo;
    
       while ( tmp -> next != NULL ) {
    
          scanf(" %d ", &(tmp->dato));
          tmp = tmp -> next;
       }
    
       *tmp = primo;
    
       while( tmp -> next != NULL)
          printf(" %d ", tmp->dato);
    
       return 0;
    }
    un po' meglio, non ti pare?

    Comunque nel tuo codice ci sono essenzialmente due problemi. Innanzitutto, il segmentation fault lo hai su questa riga:

    codice:
       *tmp = primo;
    l'istruzione di per sé sarebbe lecita, ma il punto è che tu stai cercando di assegnare al valore puntato da tmp la struct primo senza aver allocato lo spazio per tmp. Devi quindi correggere così:

    codice:
       tmp = (struct list *) malloc( sizeof(struct list) );
       *tmp = primo;
    inoltre devi togliere quegli spazi nelle stringhe di formato delle scanf() altrimenti sarai costretto a immettere due valori di cui però solo il primo viene assegnato alla variabile.

    Quindi la prima scanf(), ad esempio, diventa

    codice:
       scanf("%d", &n);
    every day above ground is a good one

  3. #3
    Grazie mille davvero, così non mi da' problemi dal punto di vista programmativo, però temo di aver sbagliato qualcosa a livello algoritmico infatti non entra mai nel secondo ciclo while e data la guardia è come se non avessi fatto l'assegnamento
    codice:
       *tmp=primo;
    percui tmp->next punta a NULL .
    Il problema è che ora alloca le liste ma non entra nel ciclo che mi fa rimpire i campo dati.
    Potreste spiegarmi cosa non va ?
    Grazie della pazienza.

  4. #4
    Utente di HTML.it
    Registrato dal
    Jul 2008
    Messaggi
    1,326
    E certo... proviamo a capire cosa stiamo combinando.

    Inizialmente tu dichiari un dato di tipo struct list che è appunto primo, assegni NULL al suo campo next (tieni a mente questo passaggio!) e al valore puntato da tmp (per il quale hai allocato l'opportuno spazio) assegni proprio primo.

    Dopo leggi n da tastiera e per n-1 volte esegui quel ciclo for che in pratica ti costruisce la lista, allocando spazio per i suoi vari nodi.

    Uscito dal ciclo, assegni NULL al campo next di tmp (giustamente, perché ora questo punta alla coda della lista, cioè all'ultimo nodo) ma dopo che fai? Riaggiorni il valore puntato da tmp a primo... ma primo aveva NULL come valore del campo next, quindi è ovvio che il flusso di controllo non entra nei cicli successivi (i predicati di entrambi, infatti, sono subito falsi).

    Il punto è che quando vai a costruire la lista, al primo passo tu non aggiorni il campo next di primo perché il valore puntato da tmp è solo una copia di quest'ultimo... è un po' come quando passi un argomento per valore ad una funzione: questa lo può anche modificare, ma nella funzione chiamante questa modifica non sarà visibile.

    Questo ti dovrebbe lasciar intuire che forse la soluzione consiste nel dichiarare primo come puntatore e cambiare un po' le cose di conseguenza (non tanto, anzi).

    Tra l'altro ti faccio notare che l'ultimo ciclo while non andrebbe bene comunque perché non aggiorni il campo next di tmp (come invece fai correttamente in quello precedente).

    Ah un'ultima cosa: quando programmi in C evita di ricorrere alle dichiarazioni sparse delle variabili nel mezzo del codice: è una caratteristica introdotta col C++.
    every day above ground is a good one

  5. #5
    ora funziona grazie YuYevon.

    ho riscritto il codice così

    codice:
    #include<stdio.h>
    #include<stdlib.h>
    
    struct list{
      int dato;
      struct list*next;
    };
    
    int main(){
      int i,n;
      struct list *primo;
      struct list *tmp;  
     
    primo=(struct list*)malloc(sizeof(struct list));
     
      primo->next=NULL;
    
      tmp=(struct list*)malloc(sizeof(struct list));
      tmp=primo;
    
      scanf("%d", &n);
      
          for(i=0;i<n-1;i++){
        
                   tmp->next=(struct list*)malloc(sizeof(struct list));
                   tmp=tmp->next;
      }
      
      tmp->next=NULL;
      tmp=primo;
      
          while((tmp->next)!=NULL){
            scanf("%d", &(tmp->dato));
           tmp=tmp->next;
      }
      scanf("%d",&(tmp->dato));
    
      tmp=primo;
       
      printf(" \n ");
     
         while(tmp->next!=NULL){
             printf(" %d ", tmp->dato);
              tmp=tmp->next;
      } 
      printf(" %d ", tmp->dato);
      
      return 0;
    }

  6. #6
    Utente di HTML.it
    Registrato dal
    Jul 2008
    Messaggi
    1,326
    Benissimo ma alla fine del codice ci va [/code] non [\code]
    every day above ground is a good one

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.