codice:
l = strlen(n)
nome = new char[l]
delete [] nome;
Il 'new' va fatto dopo un eventuale 'delete', altrimenti prima ti becchi un possibile leak e poi usi strcpy() su memoria non allocata.

Nel costruttore ti consiglio di inizializzare i puntatori a NULL, e altrove di reimpostarli a NULL se deallocati e non riallocati. Queste precauzioni ti permettono di agire in questa maniera:

codice:
if( nome != NULL )
    delete[] nome;

l = strlen( n ) + 1; // come ha osservato TGW
nome = new char[ l ];

...
Nel distruttore assicurati invece di inserire questo codice (piccola rettifica):

codice:
studente::~studente()
{
    if( nome != NULL )
        delete[] nome;

    if( cognome != NULL )
        delete[] cognome;
}
Ciao.

P.S.: credo che cmq chiamare 'delete' su NULL non crei problemi, ma dopo un po` di esperienza ti consiglio di non contarci mai..