2008-11-13 30 views
6

¿Por qué tiene los siguientes efectos? Imprime un terminal lleno de caracteres aleatorios y luego sale dejando un símbolo del sistema que produce basura al escribir en él. (Lo probé porque pensé que produciría una falla seg).¿por qué sucede esto (ver imagen)?

http://oi38.tinypic.com/r9qxbt.jpg

#include <stdio.h> 

int main(){ 
    char* s = "lololololololol"; 
    while(1){ 
     printf("%c", *s); 
     s++; 
    } 
} 

que fue compilado con:

gcc -std=c99 hello.c
+0

Por cierto, si usa un sistema * nix, generalmente puede restablecer su terminal a un estado utilizable con "sty cuerdo", aunque tendrá que escribirlo a ciegas. –

+0

Para consola Linux, puede hacer eco c –

+0

También puede escribir "reiniciar" incluso si no puede verlo, esto funciona para muchos. –

Respuesta

7

Usted se acaba de imprimir lo que está en la memoria, porque el bucle no se detiene al final de la cadena. Cada byte aleatorio se interpreta como un personaje. Segmentará la falla cuando llegue al final de la página de memoria (y entre en un territorio ilegible).

7

Debido a que tiene un bucle infinito (while(1)), y le sigue dando el valor actual del puntero (*s) y, a continuación, mover el puntero con un carácter hacia adelante (s++). Esto tiene el efecto de avanzar mucho más allá del final de la cadena en "basura" (memoria no inicializada), que se imprime en la consola como resultado.

20

Con el tiempo se segregará la falla, pero antes se imprimirán los bytes que estén en la misma página. Es por eso que ves caracteres aleatorios en la pantalla.

Esas pueden incluir secuencias de escape para cambiar (por ejemplo) la codificación de caracteres de la consola. Es por eso que terminas con un galimatías cuando escribes en la consola después de que también sale.

+0

Probablemente también sea la razón por la que él cree que se está abandonando en lugar de segfaulting; el mensaje "Fallo de segmentación" en sí mismo también se transforma en galimatías. –

7

Además de lo que dijeron los demás respecto a ignorar el carácter de terminal de cadena y simplemente imprimir lo que hay en la memoria, la razón por la cual el símbolo del sistema también es "basura" es que al imprimir un carácter "no imprimible", su sesión de terminal se dejó en un modo de carácter extraño. (No sé qué personaje es o qué cambio de modo hace, pero tal vez alguien más pueda hablar sobre eso que sabe mejor que yo).

+0

Todo depende de la emulación de terminal que esté usando, por supuesto. Xterm tiene el modo DEC VT-220 predeterminado, creo. Aquí hay una lista parcial de los códigos de control de terminal para ese modo: http://www.connectrf.com/Documents/vt220.html lists –

2

Ampliando ligeramente las respuestas dadas aquí (que son todas excelente) ... Me encontré con esto más de una vez cuando estaba empezando con C, y es un error fácil de hacer.

Un ajuste rápido a su while lazo lo arreglará. Todos los demás se le ha dado el por qué, a enganchar para arriba con la forma:

#include <stdio.h> 

int main() { 
    char *s = "lolololololololol"; 
    while (*s != '\0') { 
     printf("%c", *s); 
     s++; 
    } 
} 

Tenga en cuenta que en lugar de un bucle infinito (while(1)), estamos haciendo una comprobación de bucle para asegurar que el puntero nosotros' volver a tirar no es el terminador nulo de la cuerda, evitando así el desbordamiento que estás encontrando.

Si está completamente necesitado de while(1) (por ejemplo, si esto es una tarea y el instructor desea que lo use), use la palabra clave break para salir del ciclo.El siguiente código olores, al menos para mí, pero funciona:

#include <stdio.h> 

int main() { 
    char *s = "lolololololololol"; 
    while (1) { 
     if (*s == '\0') 
      break; 
     printf("%c", *s); 
     s++; 
    } 
} 

Ambos producen la misma salida de la consola, sin ningún salto de línea al final:

lolololololololol

1

Su loop no termina, por lo que println imprime todo lo que está en la memoria después del texto que escribe; eventualmente accederá a la memoria que no está permitida para leer, causando que falle por segmentación.

Puede cambiar el bucle como los otros sugirieron, o puede tomar ventaja de que en C, el cero es falso y nulo (que termina todas las cadenas) es también cero, por lo que se puede construir el bucle como:

while (*s) { 

en lugar de:

while (*s != '\0') 

el primero puede ser más difícil de entender, pero tiene la ventaja de la brevedad por lo que se utiliza a menudo para ahorrar un poco de escribir.

0

Además, normalmente puede volver al símbolo del sistema utilizando el comando 'reiniciar', escribiendo a ciegas, por supuesto. (escriba Enter, reset, enter)

Cuestiones relacionadas