Perché sono diversi OS, appunto. Linux/Unix utilizzano \n come carattere newline; MAC (almeno quelli vecchi, quelli *BSD based non lo so) usano/usavano \r; DOS/Windows \r\n. Questione di gusti pare.

Ne consegue che in Linux/Unix (MAC?) non esiste la concezione tra file di testo e file binario, mentre in Windows si. E la differenza è proprio quel \r in più che sballa i conti.
In pratica in modalità binaria, \r non è "strippato" da fread; in modalità testo si.
Dato che ftell() non fa questa distinzione, lei restituisce la dimensione totale del file, compresi i \r. Ma se fread() toglie i \r, leggi più caratteri di quanti fread ne fornisca. Ecco la spazzatura alla fine.
Per toglierla devi usare il valore di ritorno di fread() come indice dell'array.
codice:
    int nread = fread(contenuto,1,size,h);
    contenuto[nread]='\0';