Creo que ya te explicaron bastante bien cuál era el problema, pero por si te queda la duda de por qué comentando esa línea específica el programa te funcionaba, te digo una posible causa, que además es una buena oportunidad para que veas por qué puede ser tan complicado detectar errores en el manejo de la memoria.
Cuando un programa se ejecuta, se reserva cierto espacio de memoria para él. En una parte se coloca el código del programa, en otras los datos, (como las variables y otro tipo de información), y algo de memoria extra que reservan como previsión (por si acaso más adelante hace falta, es más eficiente tenerla ya lista). Toda esa memoria "pertenece" a tu programa. Aparte de esto, el programa puede establecer permisos para ciertas zonas de la memoria, por ejemplo, el código del programa se suele colocar en un segmento de memoria marcado como de sólo lectura. Los errores de violación de acceso/segmento se dan cuando un proceso -o programa en ejecución- intenta acceder a memoria que no le pertenece, o bien, intenta hacer algo indebido con memoria que le pertence (por ejemplo, escribir en regiones de sólo lectura), pero para simplificar, me enfoco en el primer caso.
Cuando tienes un puntero sin inicializar, como cadenados, originalmente contendrá "basura", es decir, apunta a una dirección de memoria impredecible. Si intentas acceder a ella, y se trata de una dirección que tu programa no ha reservado, se producirá el fallo. Pero si por casualidad apunta a una dirección que sí le pertenece a tu programa, puede que funcione sin problema aparente . La razón es que los errores de violación de acceso se producen a nivel de sistema operativo (con apoyo del procesador) y obviamente éste no sabe si estás usando bien o no los punteros; sólo le interesa si tu programa en general tiene permisos de acceso o no. Aún así es un error, y para muestra tu programa.
Si no te falla después del gets, significa que en tu PC, cadenados, por casualidad, está apuntando a memoria reservada por tu programa.
Dices que el error se da si descomentas esta línea:
//printf("pp->cadenatres %s\n", pp->cadenatres);
Pero ahí sólo accedes a cadenatres. Mi suposición es que la dirección a la que se inicializa por azar cadenados es la dirección del miembro cadenatres. Así, cuando gets modifica los datos apuntados por cadenados, accidentalmente estás sobrescribiendo cadenatres, que ahora está apuntando a una dirección impredecible. En este caso, probablemente a memoria que no te pertenece, y por eso el printf falla, por intentar acceder a memoria no válida.
Siguiendo con este supuesto, esto no tendría por qué fallar:
if(strcmp(cadenauno
,cadenados
)==0){
Ya que cadenados apunta a memoria "válida" (desde el punto de vista del sistema operativo).
No sé si también te funcionaba esta línea:
if(strcmp(cadenauno
,pp
->cadenatres
)==0){
pero de ser así, probablemente significa que cadenatres quedó apuntando a una dirección que está cerca del final de una región reservada por tu programa. Me explico: una cadena de C termina cuando se encuentra el caracter de fin de cadena '\0'. Así, la variable cadenauno apunta a la cadena "hola\0". Imagina que la dirección a donde quedó apuntando cadenatres contiene esto: "#5&bfdfgfgfhgh6(\0". Sería posible que los primeros, digamos 4 caracteres, apunten a memoria que anteriormente reservó el programa, y a partir del 5o caracter, entramos a memoria no válida. Eso significaría que, mientras no intentes acceder más allá de su 4o caracter, no habrá error. La función printf, naturalmente, intentará imprimir la cadena entera, y por lo tanto, fallará. El caso de strcmp es distinto, ya que desde el primer caracter detectará que las cadenas son distintas, y por lo tanto deja de procesarlas, y te devuelve el resultado, sin haber llegado nunca a intentar leer el 5o caracter, y por eso no falla.
Todo esto es sólo suposición mía, pero es una posibilidad válida, y más de una vez me he encontrado con casos así. Como ves, un error en un puntero terminaría dejando a otra variable (cadenatres) en un estado inválido, y esta última sería la que provocara fallos. Y no habría nada en el código que indique que cadenados modificó a cadenatres, por lo que, si se tratara de un programa más grande, podría ser muy difícil dar con el fallo.
La moraleja: ten mucho cuidado al manejar punteros y nunca los uses sin inicializar. Eso te evitará muchos dolores de cabeza.