Soy un estudiante aprendiendo C++, y estoy tratando de entender cómo funcionan las matrices de caracteres terminados en nulo. Supongamos que definir una matriz de caracteres así:C++ char matriz nulo ubicación del terminador
char* str1 = "hello world";
Como se esperaba, strlen(str1)
es igual a 11, y es terminada en nulo.
¿Dónde pone C++ el terminador nulo, si los 11 elementos de la matriz de caracteres anterior están llenos con los caracteres "mundo hello"? ¿En realidad está asignando una matriz de longitud 12 en lugar de 11, siendo el 12º carácter '\0'
? CPlusPlus.com parece sugerir que uno de los 11 tendría que ser '\0'
, a menos que esté hecho asignando 12.
Supongamos que yo haga lo siguiente:
// Create a new char array
char* str2 = (char*) malloc(strlen(str1));
// Copy the first one to the second one
strncpy(str2, str1, strlen(str1));
// Output the second one
cout << "Str2: " << str2 << endl;
Esto da salida a Str2: hello worldatcomY╗°g♠↕
, que supongo es C++ leer el memoria en el lugar señalado por el puntero char* str2
hasta que encuentre lo que interpreta como un carácter nulo.
Sin embargo, si a continuación, hago esto:
// Null-terminate the second one
str2[strlen(str1)] = '\0';
// Output the second one again
cout << "Terminated Str2: " << str2 << endl;
Genera Terminated Str2: hello world
como se esperaba.
Pero no escrito a str2[11]
implica que estamos escribiendo fuera del espacio de memoria asignada de str2
, ya str2[11]
es el byte 12, pero sólo se asignaron 11 bytes?
La ejecución de este código no parece causar advertencias del compilador o errores de tiempo de ejecución. ¿Es seguro hacerlo en la práctica? ¿Sería mejor usar malloc(strlen(str1) + 1)
en lugar de malloc(strlen(str1))
?
No, uno de los 11 caracteres es de hecho '\ 0' ... es broma :-) – hirschhornsalz
Como está aprendiendo, es importante que sepa desde el principio los nombres de las cosas que está aprendiendo. La expresión 'char * str1 =" hello world ";' no define una matriz de caracteres, sino un * puntero * a un literal (incidentalmente la conversión de 'const char *' a 'char *' está en desuso, por lo que el compilador debería te lo he advertido). El * literal * en sí mismo es una * matriz * de * constante * caracteres con un terminador nulo, pero la variable que ha definido es un * puntero *. –