Problemillas con los punteros ¿eh?

Las variables locales existen únicamente durante el tiempo de ejecución de la función que las contiene, excepto las declaradas como static, cuyo contenido permanece entre llamadas a la función. Si un puntero local se destruye al finalizar la función, lógicamente la variable que apuntaba a su dirección apuntará a cualquier sitio desconocido. El compilador te avisa de esto.
Prueba, en lugar de copiar la dirección del puntero utilizando el '=' , a copiar el contenido de la variable utilizando strcpy o, mejor, strncpy, ya que el signo '=' obtiene la dirección del puntero, y el contenido de ésta cambia cada vez que llamas a la función, por eso te encuentras los mismos datos en todas las variables, porque todas tienen la misma dirección de memoria. Es decir, que tendrías que declarar a uno, dos y tres como arrays de caracteres del mismo tamaño que cadena. Yo pondría ese valor en un #define:
#define LONGCAD 512
static char cadena[LONGCAD];
char uno[LONGCAD], dos[LONGCAD], tres[LONGCAD];
Por cierto, sería aconsejable que, al utilizar strncpy, el parámetro de la longitud contenga ésta menos uno, es decir, 511 para este ejemplo. Esto es para asegurarle el sitio al carácter de fin de cadena.
Salu2.