codice:
#include <stdio.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include <malloc.h>

typedef int type;

struct _list
{
    type data;
    struct _list * next; 
};

typedef struct _list * lista;

void inizializza(lista ptrls, type n);
void aggiungi(lista ptrls, type n);
void cancell(lista ptrls);

void inizializza(lista ptrls, type n)
{
    assert(ptrls != NULL);
    ptrls->data = n;
    ptrls->next = NULL;
}

void aggiungi(lista ptrls, type n)
{
    assert(ptrls != NULL);
    
    // Aggiungeresti sempre l'elemto dopo il primo, perdendo la memoria
    // allocata agli altri elementi, oltre che perdendo gli elementi stessi
    // devi scorre fino al fondo della lista per inserire un dato in una lista di questo tipo
    lista aux = ptrls;
    while( aux->next != NULL ) {
        aux = aux->next;
    }
    aux->next = (lista)malloc(sizeof(struct _list));
    aux = aux->next;
    aux->data = n;
    aux->next = NULL;
    
}

void cancell(lista ptrls)
{
    lista aux;
    while (ptrls != NULL) 
    {
        aux = ptrls;
        ptrls = ptrls->next;
        free(aux);
    }
}

int main( )
{
    lista l = (lista)malloc( sizeof(struct _list));
    inizializza(l, 9);
    aggiungi(l, 7);
    aggiungi(l, 5);
    aggiungi(l, 8);
    
    // il ciclo tralascia sempre l'ultimo elemento, ci vuole un do while per usare questa condizione
    lista aux = l;
    do {
        printf("%d \n", aux->data);
        aux = aux->next;
    } while(aux != NULL);
    cancell(l);
    system( "PAUSE" );
    return 0;
}
funziona ora ?