Intanto il distruttore di Animale dev'essere dichiarato virtual, altrimenti non saranno richiamati i distruttori delle classi derivate.
Poi in input_file immetti dati nella struttura senza prima aver allocato spazio per contenerli e questo è male.

Altra osservazione: nelle derivate utilizzi [/b]char* razza[/b]. Visto che è un dato comune (e Animale non è un'interfaccia), meglio metterlo nella classe base.

Infine:
L’allievo utilizzi, se necessario, le funzioni di libreria messe a disposizione dal linguaggio
direi di usare std::string invece dei char*, im dodo da gestire le stringhe in maniera "umana" ed evitare problemi con allocazioni dimenticate. Tanto più che non effettui una scrittura binaria sul file, ma scrivi i vari dati uno per linea.