Error de bus 10 en C: literales de cadena

¿Alguien puede explicar por qué?

char *s1 = "abcd"; char *s2 = s1; s1[0] = "z"; s1[2] = "\0"; 

me da un error de bus 10 PERO

  char s1[] = "abcd"; char *s2 = s1; s1[0] = "z"; s1[2] = "\0"; 

no?

¿char * s1 y char s1 [] no son equivalentes? Por favor explique, gracias.

¡Sé libre (de pereza histórica), sé sabio! ¡Los punteros no son matrices! Los tutoriales te han mentido!

En el primer ejemplo, está modificando un puntero a un literal de cadena constante , y eso es un comportamiento indefinido. ¡Cualquier cosa puede pasar entonces!

Mientras tanto, en el segundo caso, la cadena se almacena dentro de la matriz y la matriz se encuentra en la stack . Por lo tanto, el segundo ejemplo expone más que una matriz simple e inocente que es modificable.

Los punteros s2 no hacen ninguna diferencia en todo esto. En mi humilde opinión, el hecho de que el primer caso sea comstackble es solo una pereza histórica, también conocida como compatibilidad hacia atrás .

BTW : ¿Estás asignando literales de cadena a los char ? Eso es un comportamiento indefinido también!

En el primer caso, establece un puntero s1 a la cadena de const dirección. Las cadenas const se almacenan en el área de solo lectura y no se puede modificar. Esto significa que no puede modificar un carácter s[x] . Es UB

En el segundo caso, declara una matriz local con una cadena. En este caso, solo el valor de inicio es de solo lectura y, después de este, utiliza una matriz asignada que se puede modificar.