No, la lista a cui punta iniz non esiste proprio!
Ragiona: nel costruttore inizializzi iniz a NULL, nel distruttore scrivi:
app* p=iniz->pun;
che equivale a scrivere:
app* p=NULL->pun;
e lo stesso problema lo hai in
chiudi_tutte() nella riga:
app* p=q->pun;
Tra l'altro nella stessa funzione scrivi:
app* q = iniz;
app* p = q->pun;
delete iniz; // stessa memoria a cui ora punta q!
...
delete q->nome; // q non è più valido, nome genera un memory leak
delete q; // altro errore perché ne q ne iniz sono reinizializzati a NULL
iniz = NULL;
se fai il delete di iniz invalidi anche q.