Traccia esercizio: Simulare in C la gestione delle camere di un albergo mediante liste lineari rappresentate su un array di struct: i principali campi sono le “informazioni” (numero di camera, cliente, etc.) ed i “link” (puntatori ai nodi della lista). [Suggerimento: L’array di struct corrisponde alla memoria in cui allocare la lista delle camere libere (ListaLibera) e la lista delle camere occupate (ListaDati). È necessario creare prima la ListaLibera, inizializzando l’array dei link in modo che ogni componente punti alla componente successiva. Ogni nodo da inserire nella ListaDati, quando una camera viene assegnata ad un cliente, è prelevato dalla testa della ListaLibera ed inserito nella testa della ListaDati; mentre il nodo da eliminare dalla ListaDati, quando una particolare camera viene liberata, è restituito alla ListaLibera (in testa) per poter essere riutilizzato in seguito.]

Il programma funziona bene, l'unico problema sorge quando elimino l'ultimo elemento della lista e successivamente voglio inserirne un altro. Secondo me il problema è nella function libera ma non capisco come posso risolvere.


codice:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct
{
    int n;
    char nome[20];
}inf;
struct listalibera
{
    inf info;
    struct listalibera *next;
};
struct listadati
{
     inf info;
    struct listadati *next;
};
typedef struct listalibera l_list;
typedef struct listadati d_list;
void ins_testa(d_list **d, l_list **l)
{
    d_list *nuovo;
    nuovo=calloc(1,sizeof(d_list));
    nuovo->info.n=(*l)->info.n;
    printf("Stanza numero %d\n",nuovo->info.n);
    puts("Inserisci nome cliente: ");
    fflush(stdin);
    gets(nuovo->info.nome);
    nuovo->next=*d;
    *d=nuovo;
    l_list *l_t;
    l_t=(*l)->next;
    free(*l);
    *l=l_t;
}
void crea_l_t(l_list **testa)
{
    l_list *h;
    h=calloc(1,sizeof(l_list));
    h->info.n=1;
    h->next=*testa;
    *testa=h;
}
void crea_l(l_list **pnt)
{
    l_list *nuovo;
    int i;
    for(i=2;i<21;i++)
    {
        nuovo=calloc(1,sizeof(l_list));
        nuovo->info.n=i;
        nuovo->next=(*pnt)->next;
        (*pnt)->next=nuovo;
        *pnt=nuovo;
    }
    nuovo->next=NULL;
}

void ins_mezzo(d_list **pnt, l_list **l_h)
{
    d_list *nuovo;
    nuovo=calloc(1,sizeof(d_list));
    nuovo->info.n=(*l_h)->info.n;
    printf("Stanza numero %d\n",nuovo->info.n);
    puts("Inserisci nome cliente: ");
    fflush(stdin);
    gets(nuovo->info.nome);
    nuovo->next=(*pnt)->next;
    (*pnt)->next=nuovo;
    *pnt=nuovo;
    l_list *temp;
    temp=(*l_h)->next;
    free(*l_h);
    *l_h=temp;
}
void libera(d_list **d, l_list **l)
{
    d_list *temp;
    l_list *h;
    int n;
    temp=*d;
    puts("Quale camera devi liberare?");
    printf("La numero ");
    scanf("%d",&n);
    while(temp->info.n!=n)
    {
        temp=temp->next;
    }
    h=calloc(1,sizeof(l_list));
    h->info.n=temp->info.n;
    h->next=*l;
    *l=h;
    d_list *cur, *prev;
    for(cur=*d, prev=NULL; cur!=NULL && cur->info.n!=n; prev=cur, cur=cur->next);
    prev->next=cur->next;
    free(cur);
}
void libera_t(d_list **d, l_list **l)
{
    l_list *h;
    d_list *temp;
    temp=*d;
    h=calloc(1,sizeof(l_list));
    h->info.n=temp->info.n;
    h->next=*l;
    *l=h;
    temp=(*d)->next;
    free(*d);
    *d=temp;
}
void visualizza_d(d_list *d)
{
    if(d==NULL)
        puts("Non ci sono capere occupate.");
    else
    {
        puts("Camere occupate:");
        while(d!=NULL)
        {
            printf("Numero camera: %d\n",d->info.n);
            printf("Nome cliente: %s\n", d->info.nome);
            d=d->next;
        }
    }
}
void visualizza_l(l_list *l)
{
    if(l==NULL)
        puts("Non ci sono capere libere.");
    else
    {
        puts("Camere occupate:");
        while(l!=NULL)
        {
            printf("Numero camera: %d\n",l->info.n);
            l=l->next;
        }
    }
}

int main()
{
    l_list *l_head, *l_punt;
    d_list *d_head, *d_punt;
    l_head=NULL;
    d_head=NULL;
    l_punt=calloc(1,sizeof(l_list));
    crea_l_t(&l_head);
    l_punt=l_head;
    crea_l(&l_punt);
    int sc;
    while(sc!=6)
    {
        puts("Menu':\n1) Occupa stanza\n2) Libera stanza\n3) Visualizza camere occupate.\n4) Visualizza camere libere.\n5) Termina programma.");
        scanf("%d",&sc);
        switch(sc)
         {
             case 1: if(d_head==NULL){
                            ins_testa(&d_head,&l_head);
                            d_punt=d_head;
                            }
                        else
                            ins_mezzo(&d_punt,&l_head);
                         break;
             case 2 : if(d_head->next!=NULL)
                            libera(&d_head, &l_head);
                          else
                            libera_t(&d_head, &l_head);
             break;
             case 3 : visualizza_d(d_head);
             break;
             case 4: visualizza_l(l_head);
         }
    }
    return 0;
}