codice:
free(s); 
return(s);
Così ti va in crash il programma di sicuro se usi s dopo che la funzione ha ritornato.E' assolutamente sbagliato!

Tieni presente che nel tuo caso specifico tu hai s che è una variabile PUNTATORE, locale alla funzione,ebbene la variabile puntatore ha una durata limitata al tempo di esecuzione ma la memoria allocata con malloc a cui quella variabile PUNTA non viene affatto liberata automaticamente all'uscita.tu ritornando s non fai che creare un nuovo puntatore (il cui nome non è meglio specificato) dello stesso tipo di s e farlo puntare esattamente dove puntava s.In questo modo all'esterno della funzione puoi assegnare il valore di ritorno suddetto ad una variabile puntatore (locale alla funzione chiamante stavolta),chiamiamola t.una volta che hai fatto le tue brave cose con t puoi e devi invocare free(t) altrimenti la memoria nn verrà liberata(quantomeno fino al termine del prog.Claro?