Strutture 'linkate'

di il
12 risposte

Strutture 'linkate'

Salve, vi scrivo per sapere se qualcuno di voi mi può aiutare a risolvere un problema riscontrato nella compilazione di un programma in c riguardante le strutture linkate.
struct data
{
  char nome [20];
  struct data *NEXT ; 
};

typedef struct data LISTANOMI ; /* Lista di nomi del tipo */
typedef struct data *LINK ;

LINK head = NULL ; /*Inizio Lista (Head)*/
LINK newelem = NULL ;  /*Nuovo Elemento della Lista (Newelem) */
LINK current = NULL ; /*Posizione corrente nella Lista (Current)*/


/* Funzione per visualizzare la schermta prima di passare alla successiva */

void insertend()
{

  char name[20];

  current = head;

  while (current -> NEXT != NULL)
  {
   current = current -> NEXT;
  }
/* Alloca la casella contente il valore da inserire nella lista */
  newelem=(LINK)malloc(sizeof(LINK));
  current -> NEXT = newelem;
  newelem -> NEXT = NULL;
  printf("\nInserire nome da accodare alla lista: ");
  scanf("%s",name);
  strcpy(newelem -> nome, name);
  printf("\n");

}

void erase()
{
/* Variabile logica inizializzata su falso */
  int trovato=0;

/* Variabile che indica l'elemento da trovare */
  char key[25];

/* Torna ad inizio Lista */
  current = head;

/* Inserisci la chiave di ricerca dell'eliminazione del file */
  printf("\nQuale nome vuoi eliminare?");
  scanf("%s",key);

  do
  {
   if ( strcmp(current -> nome,key) == 0 )
   {
    printf("Eccolo!");
    trovato = 1; 
   }
   current = current -> NEXT;
  } 
  while ((current != NULL) && (trovato == 0));

   if (trovato == 0)
    printf ("\nElemento non trovato!!!");
}

void displaylista ()
{
/* Indice contatore inizializzato a 0 */
  int i=0;

/* Cambia la posizione corrente con la testa, in modo da trovarsi in testa alla lista
*/
  current = head ;

/* Stampa un form a video che contenga la lista */
  printf ("\n" );
  printf ("Lista corrente\n" );

/* Ciclo while che stampa gli elementi della lista */
  while (current != NULL )
  {
/* Contatore che permette la visualizzazione della posizione */
/* di un elemente nella lista
*/
   i++;

/* Stampa a video la posizione dell'elemnto nella lista */
   printf ("%d " ,i);

/* Stampa gli elementi nella lista */
    printf (">    %s\n" , current -> nome );

/* Avanza nella lista */
    current = current -> NEXT ;
   }
}

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "liste_menu.c" /* Carica le procedure delle funzioni */

main ()
{
  int scelta;

  printf ("Scegli l'operazione da eseguire:\n\n" );
  printf (" 2 - Accoda un elemento nella lista\n" );
  printf (" 3 - Cancella un elemento\n" );
  printf (" 4 - Visualizza la lista \n" );
  printf ("\n" );
  printf ("Scegli: " );
  scanf ("%d" ,&scelta );

  switch (scelta )
  {

   case 2:
    insertend (); /* Inserisci in coda alla lista */
   break ;

   case 3:
     erase (); /* Cancella un elemento dalla lista */
   break ;

   case 4:
    displaylista (); /* Visualizza la lista */
   break ;
  }

return 0;

}
Non riesco ad individuare l'errore, che sicuramente sarà dovuto ad una mal allocazione di memoria o ad un uso non proprio dei puntatori; il messaggio di errore visualizzato è il seguente: "Errore di segmentazione (core dump creato)".
Vi ringrazioe anticipatamente

12 Risposte

  • Re: Strutture 'linkate'

    Il codice completo è quello che hai postato?

    Se così te lo lascia compilare?
  • Re: Strutture 'linkate'

    Si, l'eseguibile viene creato ma quando decido di inserire o di eliminare(operazione impossibile da eseguire essendo vuota) mi da l'errore : "Errore di segmentazione (core dump creato)".
  • Re: Strutture 'linkate'

    Il problema sta nel fatto che i puntatori newelm, current ed head sono null, quindi non puntano a nulla.

    Ad ogni modo, penso debba rivedere la modularità del programma.
    Ho l'impressione che stai cercando di scrivere una libreria; ma la scrivi in maniera anomala nel senso che hai due file ma in realtà è un'unico monoblocco del main, con le variabili e funzioni scritte appunto prima del main, nei fatti non modularizza. (Non lo so se è proprio quello che vuoi)

    Ad ogni modo il segmentation fault è dato dai puntatori NULL che poi li utilizzi subito nelle funzioni, insertend, ecc...
  • Re: Strutture 'linkate'

    Hai ragione per le librerie avrei dovuto creare un'altro file. Invece ho provato ad eliminare l'inizializzazione di LINK head LINK newelem LINK current, ma nonostante la modifica l'errore si ripresenta.
  • Re: Strutture 'linkate'

    Ho anche provato a compattare i due file, ma non riesco a compilare in quanto viene visualizzato questo errore
    a.c:56:6: warning: conflicting types for ‘insertend’ [enabled by default]
     void insertend()
          ^
    a.c:39:5: note: previous implicit declaration of ‘insertend’ was here
         insertend (); /* Inserisci in coda alla lista */
         ^
    a.c:78:6: warning: conflicting types for ‘erase’ [enabled by default]
     void erase()
          ^
    a.c:43:6: note: previous implicit declaration of ‘erase’ was here
          erase (); /* Cancella un elemento dalla lista */
          ^
    a.c:108:6: warning: conflicting types for ‘displaylista’ [enabled by default]
     void displaylista ()
          ^
    a.c:47:5: note: previous implicit declaration of ‘displaylista’ was here
         displaylista (); /* Visualizza la lista */
         ^
    
  • Re: Strutture 'linkate'

    LINK head è un puntatore ad una struttura che non esiste, va prima allocata. Altirmenti non sai come farla puntare ai vari campi.

    Spero averti dato uno spunto.
  • Re: Strutture 'linkate'

    TI ringrazio per i suggerimenti ma penso di non aver capito molto bene il meccanismo... Ho provato ad adattare un programma preesistente modificando il tipo di dato: da int a char.
    #include <stdio.h>
    #include <assert.h>
    #include <stdlib.h>
    #include <string.h>
    #define M 10
    
    struct SInfo {
     
     char utente[M];
    };
    typedef struct SInfo TInfo;
    
    
    struct SNode {
     
     TInfo info;
     struct SNode *link;
    
    };
    
    typedef struct SNode TNode;
    typedef TNode *TList;
    
    TList Crea_Lista();
    
    TList Inserisce_Elemento(TList lista, TInfo info);
    void Stampa_Lista(TList lista);
    
    int main() {
    
     TList lista;
     TInfo info[M];
    
     lista = Crea_Lista();
     
    
     printf("Inserire il nome da aggiungere\n");
     scanf("%s", info->utente);
    
     lista = Inserisci_Elemento(lista,info);
    
     Stampa_Lista(lista);
    
    return 0;
    
    }
    
    TList Crea_Lista() {
     
     return NULL;
    
    }
    
    
    TList Inserisce_Elemento(TList lista, TInfo info) { //
    
     TList newnode;
     newnode = (TNode *)malloc(sizeof(TNode));
     assert(newnode != NULL); 
     newnode->info = info;
     newnode->link = NULL;
     
     return newnode;
    
    }
    
    void Stampa_Lista(TList lista) {
    
     TList curr;
     curr = lista;
    
     while(curr != NULL) {
     
      printf("%s",curr->info.utente);
      curr = curr->link;
     }
    
    }
    
    ma purtropp ottengo questo errore:
    r.c: In function ‘main’:
    r.c:40:8: warning: assignment makes pointer from integer without a cast [enabled by default]
      lista = Inserisci_Elemento(lista,info);
            ^
    /tmp/ccK8SXna.o: nella funzione "main":
    r.c:(.text+0x4a): riferimento non definito a "Inserisci_Elemento"
    collect2: error: ld returned 1 exit status
    
    . Per caso sapresti dirmi come aggiustare il codice in modo da poterlo compilare? Grazie di tutto.
  • Re: Strutture 'linkate'

    Hai necessità di vedere bene l'allocazione dinamica ed approfondire l'uso dei puntatori e il passaggio di parametri alle funzioni.

    Ci sono molte cose che non vanno nel tuo codice.

    Se vuoi che compili, ma continuerà a non funzionare perchè le funzioni non sono scritte correttamente ecco un modo:
    
    int main() {
    
        TList lista;
        TInfo info[M];
        int i=0;
    
        lista = Crea_Lista();
    
        while(i<M) {
            printf("Inserire il nome da aggiungere\n");
            scanf("%s", info->utente);
    
            lista = Inserisce_Elemento(lista,info[i]);
            i++;
        }
        Stampa_Lista(lista);
    
        return 0;
    
    }
    
    Ti consiglio di approfondire i concetti che ti ho detto sopra, sarà difficile adattare programmi scritti se non si è compreso che cosa si vuol fare. Perdonami la shiettezza!

    Se hai difficoltà, posta le specifiche del problema e proverò a darti suggerimenti su cosa implementare e come.

    P.s.
    Hai studiato la modularità? Gli header file? Di solito queste cose si fanno costruendo librerie ad hoc.
  • Re: Strutture 'linkate'

    Non ti preoccupare anzi ti ringrazio, comunque sono argomenti che sto affrontando da poco e non ho molta dimestichezza, anzi.. Comuque ti ringrazio, vedo di ripassare gli argomenti che mi hai consigliato e riprovo a scrivere il codice.
    Grazie.
  • Re: Strutture 'linkate'

    Nonostante abbia perso gran parte della mia credibilità, sono riuscito a tirar fuori un'altro programma, più semplice, che prende dei valori da schermo li mette in lista e poi li stampa.. riesco a creare l'eseguibile, ma non riesco a salvare i valori visto che la stampa avviene senza valori. Sto sbagliando con la memoria dinamica o coi puntatori? o peggio entrambi?
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    
    # define M 10
    
    typedef char element_type;
    
    typedef struct list_element {
    
     element_type value[M];
     struct list_element *next;
    
    } item;
    
    typedef item *list;
    
    void showlist (list l);
    
    int  main(void)
    {
     list root=NULL, aux;
     char n[M];
     int max;
     int i=0;
    
     printf("Inserire max numer oclienti\n");
     scanf("%d", &max);
    
     while (i<max)
     {
      if (root==NULL) 
      {
       root=(list)malloc(sizeof(struct list_element));
       aux=root;
      }
      else
      { 
       aux->next=(list)malloc(sizeof(struct list_element));
       aux=aux->next;
      }
      
      scanf("%s", n);
      strcmp(aux->value,n);
      aux->next = NULL;
      i++;
    }
    
    showlist(root);
    
    return 0;
    }
    
    
    
    void showlist (list l)
    { 
     printf("[");
    
     while (l!=NULL)
     {
      printf("%s",l->value);
      l=l->next;
    
      if (l!=NULL) 
       printf (","); 
     }
       printf("]\n");
    }
    
    
    
    
    Grazie, perdona la mia insistenza.
  • Re: Strutture 'linkate'

    Nel codice che hai postato funziona tutto a patto di sostituire la strcmp con la strcpy.

    strcpy(aux->value,n);

    Vuoi copiare la stringa letta nella lista, non confrontare qualcosa.

    Attento! Non sottovalutare i warning che il compilatore it da.
  • Re: Strutture 'linkate'

    Fantastico grazie mille, comunque strano durante la compilazione non mi da nessun warning. Grazie mille comunque per il tempo.
Devi accedere o registrarti per scrivere nel forum
12 risposte