¿Cómo es que printf está imprimiendo una cadena que no termina en nulo?

El libro de progtwigción en c dice que mi cadena debe estar terminada en nulo para imprimirla con printf, pero el siguiente progtwig imprime la cadena a pesar de que no está terminada en nulo.

#include  #include  int main(){ int i ; char str[10] ; for(i = 0 ; i < 10 ; i++ ) { str[i] = (char)(i+97) ; } printf("%s",str) ; } 

Estoy utilizando IDE de codeblocks.

Es un comportamiento indefinido leer más allá de los límites de una matriz, en realidad no tuvo suerte , no se bloqueó, si lo ejecuta suficientes veces o si lo llama en una función que puede (o no) bloquearse, siempre debe terminar la cadena. o use un especificador de ancho:

 printf("%.10s", str); 

Lo que sea después del elemento 10 de str pasa a ser nulo. Ese nulo está fuera de los límites definidos de la matriz, pero C no tiene verificación de límites de matriz. Es solo suerte en tu caso que así fue como funcionó.

De acuerdo con el estándar C, la función printf imprime el carácter en la cadena hasta que encuentra un carácter nulo. De lo contrario, después del índice de matriz definido, no se definirá lo que hará. He probado su código. y después de imprimir “abcdefghij imprime un valor de basura.

Si hace otras cosas antes de esa llamada, su área de stack contendrá datos diferentes a los no utilizados. Imagina eso:

 #include  #include  #include  int use_stack(void) { char str[500]; memset(str, 'X', sizeof(str)); printf("Filled memory from %p to %p.\n", &str, &str+sizeof str); } void print_stuff() { int i; char str[16]; // changed that so that 10..15 contain X for(i = 0; i < 10; i++) { str[i] = (char)(i+97); } printf("%s",str); // have a line break before ? Then it comes from i. printf("&str: %p\n", &str); printf("&i: %p\n", &i); // Here you see that i follows str as &i is &str + 16 (0x10 in hex) } int main() { use_stack(); print_stuff(); } 

su área de stack estará llena de X es y printf() los verá.

En su situación y su entorno, la stack se “limpia” casualmente en el inicio del progtwig.

EDIT: Esto puede o no puede suceder. Si el comstackdor coloca la variable i inmediatamente después de la matriz, sus datos, sin embargo, serán terminados en NUL , porque el primer byte es el valor de i (que usted también imprime, podría ser una ruptura libne en su caso) y el 2do byte es un byte NUL . Incluso si este es el caso, su código invoca a UB (comportamiento indefinido).

¿Puede echar un vistazo (canalizando la salida del progtwig en hexdump o similar) si su salida contiene un carácter 0A ? Si es así, mi conjetura es correcta. Acabo de probarlo, y en mi comstackdor ( gcc ) parece ser el camino.

Como se dijo, nada de lo que debas confiar.

EDIT2: Si ve un salto de línea antes de , mi suposición fue correcta. Y si echa un vistazo a los punteros que se están imprimiendo, puede comparar sus direcciones en la memoria.

Debido a que en el modo de depuración, *(str+10) y todo el espacio no utilizado tienen un valor inicializado ‘0’, por lo que parece que se terminó 0.

 bash-3.2$ clang -O0 tc -ot #compile in debug mode bash-3.2$ ./t abcdefghij bash-3.2$ clang -O2 tc -ot #compile with optimization bash-3.2$ ./t abcdefghij2÷d=