Как правильно использовать nullptr?
В настоящее время я читаю "Тур по С++" by Byarne Stroustrup. Что имеет значение: на "указателях, массивах и ссылках" он привел пример об использовании nullptr
следующим образом:
int count_x(char* p, char x)
// count the number of occurrences of x in p[]
// p is assumed to point to a zero-terminated array of char (or to nothing)
{
if (p == nullptr) return 0;
int count = 0;
for (; p != nullptr; ++p)
if (*p == x)
++count;
return count;
}
В моем основном:
int main(){
char* str = "Good morning!";
char c = 'o';
std::cout << count_x(str, c) << std::endl;
return 0;
}
Когда я запускаю программу, она выходит из строя. Я получаю исключение, созданное в строке
if (*p == x)
Если я изменил цикл таким образом:
for (; *p; p++)
if (*p == x)
++count;
Теперь все работает отлично! Я использую MSVС++ 14.0.
- Тот же код, что и я, на
ideone
Я не получаю исключение, но результат всегда 0
, который должен быть 3
:
https://ideone.com/X9BeVx
Ответы
Ответ 1
p != nullptr
и *p
выполняют очень разные проверки.
Первая проверяет, что сам указатель содержит непустой адрес. Хотя последний проверяет, что адрес, на который указывает, содержит то, что не равно 0. Очевидно, что в цикле явно указано содержимое буфера, а другое - нет.
Вы segfault, потому что вы никогда не прекращаете чтение буфера (допустимый указатель вряд ли произведет null, когда он будет увеличен). Таким образом, вы получаете доступ за пределы вашего ограничения на буфер.
Ответ 2
Помните, что вы используете функцию языка C.
Ваша проблема в вашем цикле for
. После того, как указатель достигнет последнего элемента массива символов , он указывает на конец массива, а не на nullptr
.
Представьте, что у вас есть массив символов, такой как const char *a ="world"
и ptr
, указывает на
+-----+ +---+---+---+---+---+---+
ptr :| *======> | w | o | r | l | d |\0 |
+-----+ +---+---+---+---+---+---+
последний элемент, который ptr указывает на '\0'
, а в вашем for
вы должны изменить свой код, как показано ниже:
for (; *p != 0; p++) {
if (*p == x)
++count;
}
вывод: 3