Расположение нулевого терминатора символьного массива C++

Я изучаю 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) )?

13
задан John Mahoney 6 April 2012 в 23:06
поделиться