Я изучаю C++ и пытаюсь понять, как работают массивы символов, завершающиеся нулем-. Предположим, я определяю массив символов следующим образом:
char* str1 = "hello world";
Как и ожидалось, strlen(str1)
равно 11 и завершается нулем-.
Куда C++ помещает нулевой терминатор, если все 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) )
?