Sono uno studente che apprende il linguaggio C++ e sto cercando di capire come funzionano gli array di caratteri con terminazione null. Supponiamo che io definisco un array di caratteri in questo modo:Ubicazione del terminatore null dell'array di caratteri C++
char* str1 = "hello world";
Come previsto, strlen(str1)
è uguale a 11, ed è terminata da null.
Dove C++ inserisce il terminatore null, se tutti gli 11 elementi del char array sopra sono riempiti con i caratteri "ciao mondo"? Assegna in realtà una matrice di lunghezza 12 anziché 11, con il 12 ° carattere '\0'
? CPlusPlus.com sembra suggerire che uno dei 11 sarebbe necessaria '\0'
, a meno che sia effettivamente assegnando 12.
Supponiamo che procedere nel seguente modo:
// 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;
Questo fornisce in uscita Str2: hello worldatcomY╗°g♠↕
, che presumo sia C++ leggere la memoria nella posizione indicata dal puntatore char* str2
finché non incontra ciò che interpreta come un carattere nullo.
Tuttavia, se poi faccio:
// Null-terminate the second one
str2[strlen(str1)] = '\0';
// Output the second one again
cout << "Terminated Str2: " << str2 << endl;
Produce Terminated Str2: hello world
come previsto.
Ma non iscritto al str2[11]
implica che stiamo scrivendo al di fuori dello spazio di memoria allocato di str2
, dal momento che str2[11]
è il 12 ° di byte, ma assegnati solo 11 byte?
L'esecuzione di questo codice non sembra causare avvisi del compilatore o errori di runtime. È sicuro farlo in pratica? Sarebbe meglio usare malloc(strlen(str1) + 1)
anziché malloc(strlen(str1))
?
No, uno degli 11 caratteri è effettivamente '\ 0' ... sto scherzando :-) – hirschhornsalz
Dato che stai imparando, è importante che tu sappia dall'inizio i nomi delle cose che stai imparando. L'espressione 'char * str1 =" ciao mondo ";' non definisce un array di caratteri, ma un * puntatore * a un valore letterale (incidentalmente la conversione da 'const char *' a 'char *' è deprecata, quindi il compilatore dovrebbe ti ho avvertito). Il * letteral * stesso è un * array * di * constant * caratteri con un terminatore null, ma la variabile che hai definito è un * pointer *. –