Devo implementare una LIFO in C tramite una lista doppia. Ho creato un stack.c e un stack.h che mi gestiscono le operazioni sullo stack. C'è anche un item.c e un item.h che mi gestiscono delle operazioni sul nuovo tipo da me definito item come la stampa e l'acquisizione (in questo caso item è un int per semplicità).

Il programma sembra funzionare fino a quando non elimino dallo stack un elemento. Se dopo l'eliminazione provo a stampare, il programma smette di funzionare. Se invece dopo l'eliminazione inserisco un nuovo dato nello stack e stampo allora tutto fila liscio.
Sapete darmi una mano?

In stack.h ho definito struck stack come stack_t attraverso una typedef.
Nel main userò stack_t* in modo da creare un ADT.
Vi posto di seguito lo stack.c

codice:
typedef struct nodo nodo_t;

struct nodo{
    item val;
    nodo_t *next;
    nodo_t *prev;
};

struct stack {
    nodo_t *head;
    nodo_t *tail;
    int num;
};
codice:
stack_t* stack_alloc()
{
    stack_t* st;
    st = malloc(sizeof(*st));

    if (st == NULL){
        return 0;
    }

    st->head = NULL;
    st->tail = NULL;
    st->num = 0;

    return st;
}
codice:
int stack_put(stack_t* st, item d)
{
    nodo_t* nodo;

    if (st == NULL){
        return 1;
    }

    nodo = malloc(sizeof(*nodo));
    nodo->val = d;
    nodo->next = NULL;

    if (st->head == NULL){
        st->head = nodo;
        nodo->prev = NULL;
    }
    else{
        nodo->prev = st->tail;
        st->tail->next = nodo;
    }

    st->tail = nodo;
    (st->num)++;

    return 0;
}
codice:
int stack_get(stack_t* st, item* delete_d)
{
    nodo_t* nodo;

    nodo = st->tail;
    if (nodo == NULL)
        return 1;

    *delete_d = nodo->val;
    st->tail = /*st->tail->prev*/ nodo->prev;

    if (st->tail == NULL)
        st->head = NULL;

    free(nodo);
    (st->num)--;

    return 0;
}
codice:
void stack_print(stack_t* st)
{
    nodo_t* nodo;

    if ((st == NULL) || (st->num == 0))
        printf ("Nessun dato da stampare\n\n");

    else{
        printf ("ELENCO DEI DATI IN CODA:\n");

        nodo = st->head;
        while (nodo != NULL) {
            stampa_item (nodo->val);
            nodo = nodo->next;
        }
    }

    return;
}
codice:
void stack_free(stack_t* st)
{
    nodo_t* nodo;
    nodo_t* head;

    if (st == NULL)
        return;

    head = st->head;
    while (head != NULL) {
        nodo = head;
        head = head->next;
        free(nodo);
    }

    free(st);

    return;
}