Я учащийся, изучающий С++, и я пытаюсь понять, как работают массивы символов с нулевым символом. Предположим, что я определяю массив char следующим образом:
char* str1 = "hello world";
Как и ожидалось, strlen(str1)
равно 11, и оно заканчивается нулем.
Где С++ помещает нулевой ограничитель, если все 11 элементов из вышеприведенного массива char заполнены символами "hello world"? На самом деле он выделяет массив длиной 12 вместо 11, а 12-й символ - '\0'
? CPlusPlus.com кажется, что один из 11 должен быть '\0'
, если он действительно не выделяет 12.
Предположим, что я делаю следующее:
// 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;
Это выводит Str2: hello worldatcomY╗°g♠↕
, который, как я полагаю, является С++, читающим память в местоположении, на которое указывает указатель char* str2
, до тех пор, пока он не встретит, что он интерпретирует как нулевой символ.
Однако, если я тогда сделаю это:
// Null-terminate the second one
str2[strlen(str1)] = '\0';
// Output the second one again
cout << "Terminated Str2: " << str2 << endl;
Он выводит Terminated Str2: hello world
, как ожидалось.
Но не пишет ли в str2[11]
, что мы пишем вне выделенного пространства памяти str2
, так как str2[11]
является 12-м байтом, но мы выделили только 11 байтов?
Запуск этого кода, похоже, не вызывает каких-либо предупреждений компилятора или ошибок во время выполнения. Безопасно ли это делать на практике? Было бы лучше использовать malloc( strlen(str1) + 1 )
вместо malloc( strlen(str1) )
?