L'errore è qua:

codice:
void crea_array(int *a,int n){

  a=(int *)malloc(sizeof (int)*n);
}
In c gli argomenti delle funzioni sono passati per Valore; questo significa che quando passi un argomento viene creata una copia dell'argomento stesso che è la variabile effettivamente usata nella funzione. crea_array riceve come parametro un 'puntatore a int' "a"; l'argomento "a" è solo una copia del puntatore "vett" che passi nella chiamata della funzione, per questo, finita la funzione, "vett" non punterà al valore restituito da malloc. Le soluzioni sono due:

1 - ritonare il valore della malloc:

codice:
int * crea_array(int n){
  return (int *)malloc(sizeof(int) * n);
}
e quindi chiamare crea_array così:

vett = crea_array(dim);


2 - Se una funzione deve modificare l'argomento, non bisogna passare l'argomento stesso, ma un puntatore all'argomento. Qual è qui l'argomento da modificare? "vett", quindi bisogna passare un puntatore a "vett":

crea_array(&vett, dim);

e ovviamente la crea_array dovrà prendere un putnatore a un puntatore a int:

codice:
void crea_array(int **a,int n){
  //Con l'istruzione successiva imposto il valore di vett
  *a=(int *)malloc(sizeof (int)*n);
}