No terminando en nulo una cadena de estilo C

Dada una cuerda, digamos,

char *str = "Hello,StackOverflow!" char newStr[30]; int l = strlen(str); for(int i =0 ; i<l ; i ++ ) newStr[i] = str[i]; printf("%s" , newStr); 

Ahora, sabemos que el último carácter de una cadena-c debe ser '\0' , ya que aquí no hemos hecho explícitamente lo mismo (almacén ‘\ 0’ en el último índice de la cadena newStr), este progtwig debería fallar ya que printf no encontrará el final de la cadena.

Pero noté que funcionaba bien a veces y otras veces no. Cual podría ser el problema ? Estaba trabajando casi todo el tiempo en realidad. ¿No se supone que debe fallar o dar algún error en tiempo de ejecución?

¿Será el mismo caso en C ++ también?

No. Invoca un comportamiento indefinido, significa que no tiene que bloquearse , puede hacer literalmente cualquier cosa, como los demonios nasales.

Además, “da un error de tiempo de ejecución”, bueno, eso depende de lo que quiere decir con un error de tiempo de ejecución. No hay tiempo de ejecución dynamic para C: si espera un mensaje de error bien formateado de una excepción, eso no sucedería. Lo que sucedería es probablemente una falla de segmentación.

En general, si uno causa / usa un comportamiento indefinido, no debe confiar en que se bloquee o que no se caiga.

Un “choque” no está garantizado. Un progtwig que maneja incorrectamente los terminadores nulos en las cadenas (en general, accede a los datos fuera de los límites del búfer) o viola la printf formato printf , puede parecer que funciona bien, funcionando y no causando un fallo de seguridad. Pero esto es solo una casualidad: el comportamiento de su código no está definido.

Será lo mismo en C ++.

Sospecho que la mayor parte del tiempo seguiría imprimiendo más allá del “!” y sigue en la memoria hasta que llegue a NULL. Lo que podría resultar en un choque, pero no tiene que hacerlo.

Por eso es mejor:

 memset(newStr, 0, 30); 

o

 // This works because string literals guarantee a '\0' is present // but the strlen returns everything up until the '\0' int l = strlen(str) + 1; 

esto también funciona, pero no creo que sea tan claro como agregar uno a strlen:

 for(i =0 ; i<=l ; i ++ ) 

Como la definición de strlen implica que necesita.

Por casualidad, la mayoría de las veces, los bytes sin inicializar en newStr resultan ser 0 en su caso particular.

Su progtwig tiene un comportamiento indefinido, ya que promete llamar a printf con un puntero a una cadena terminada en cero, pero no lo hace. Cualquier cosa podría pasar, pero su progtwig simplemente no es correcto.

Específicamente, mientras lee los elementos de la matriz uno por uno para encontrar el terminador nulo, el progtwig finalmente accederá a una variable sin inicializar, que es UB.

El comportamiento de los bytes de lectura que no se han inicializado como caracteres no está definido en la mayoría de las implementaciones de C. A veces, printf puede escribir basura, a veces el progtwig puede encontrar un byte nulo 0 después del último carácter y terminar normalmente. En algunos casos raros puede causar un accidente. Esta es la razón por la que está viendo variaciones en lo que sucede cuando ejecuta el progtwig. Depende del comstackdor que esté utilizando y de lo que haya en la ubicación de la memoria después de lo que está asignando para la matriz.

(Es decir, si su progtwig se comstackra, ha dejado un punto y coma)