¿Por qué la cadena se altera después de strcat ()?

este es el código fuente

int main() { char str[]="dance"; char str1[]="hello"; char str2[]="abcd"; strcat(str1,str2); printf("%s",str); } 

salidabcd

por qué se cambia str después de strcat(str1,str2);

str1 no tiene suficiente espacio para concatenar la cadena str2 . Esto invoca un comportamiento indefinido . Usted puede obtener cualquier cosa. Resultado esperado o inesperado.
Ahora prueba esto:

 #include  #include  int main(void) { char str[]="dance"; char str1[10]="hello"; char str2[]="abcd"; strcat(str1,str2); printf("%s\n",str1); printf("%s\n",str); return 0; } 

Salida:

 helloabcd dance 

Entiendo…

Como no he dado el tamaño de str1 , tanto str1 como str están presentes en la memoria una tras otra

me gusta

 hello \0 dance 

así que cuando concateno str1 y str2 , sucede lo siguiente …

 a replaces \0 b replaces d c replaces a d replaces n \0 replaces c 

y por lo tanto se altera str

Este es un “comportamiento indefinido”

str , str1 , str2 tienen un tamaño limitado, y se colocan en la stack, la secuencia depende del comstackdor. Probablemente tengas algo como esto en tu stack.

['a']['b']['c']['d']['\0']['h']['e']['l']['l']['o']['\0']['d']['a']['n']['c']['e']['\0']

¿Lo tengo?

Cuando escribe después del tamaño inicial de str1 , está anulando la stack, cambiando todas las demás variables que están en la stack.

Está concatenando str2 a str1 , pero str1 no es lo suficientemente grande como para contener ambas cadenas. Hay un desbordamiento de búfer que corrompe el contenido de la tercera cadena en la stack, str .

Cuando se define

 char str1[] = "hello"; 

crea una matriz de seis caracteres, 5 para “hola” más un carácter nulo para terminar la cadena. La cadena ya está llena, por así decirlo. Una solución rápida es especificar un tamaño de matriz:

 char str1[20] = "hello"; 

Ahora debería poder agregar str2 a str1 con strcat .

En la práctica, debe asegurarse de que el búfer sea lo suficientemente grande como para contener toda la cadena:

 char buf[20]; if (strlen(str1) + strlen(str2) < 20) { strcpy(buf, str1); strcat(buf, str2); } 

Esto es tedioso. Hay otra forma de concatenar cadenas sin desbordamiento de búfer:

 char buf[20]; int n; n = snprintf(buf, 20, "%s%s", str1, str2); 

Esto puede cortar toda la cadena corta, pero no desbordará el búfer. El valor de retorno n indica cuántos caracteres se habrían escrito si hubiera habido suficiente espacio, por lo que puede usarlo para verificar.