Код C:Почему я получаю длину 7, когда применяю strlen() к указателю на один символ?
char c = 'a';
char *p = &c;
printf("%lu\n",strlen(p));
И я получаю результат 7, и я понятия не имею, как это 7 выйти.
Код C:Почему я получаю длину 7, когда применяю strlen() к указателю на один символ?
char c = 'a';
char *p = &c;
printf("%lu\n",strlen(p));
И я получаю результат 7, и я понятия не имею, как это 7 выйти.
Помните, что строки в C действительно называются байт-строки с нулевым завершением. Все строки заканчиваются одним символом '\0'
, что означает, что односимвольная строка на самом деле равна . Два символа: один символ плюс терминатор.
Если у вас есть указатель, указывающий на код c
, у вас нет двух символов, только для одиночных символов, содержащихся в c
. Вы не знаете, есть ли терминатор после этого символа в памяти, поэтому, когда strlen
ищет этот терминатор, он передаст персонажа и выйдет в память, не принадлежащую какой-либо строке, чтобы искать его, и у вас будет неопределенное поведение .
попробовать проиллюстрировать то, что у вас есть, посмотрите на этот «графический» представление:
+---+ +-----+---------------------- | p | --> | 'a' | indeterminate data... +---+ +-----+----------------------
Это в основном, как она выглядит в памяти. Переменная p
указывает на место, где хранится ваш символ, но после этого в памяти находятся только неопределенные данные. Это будет казаться случайным, и вы не можете определить, где будет байт, соответствующий символу терминатора строк.
Невозможно сказать, почему strlen
получает значение 7
, за исключением того, что он обнаруживает шесть бесконечных байтов в неопределенных данных после вашего символа. В следующий раз, когда вы запустите его, или если вы запустите его в другой системе, вы можете получить совершенно другой результат.
Да, я знаю, что strlen будет искать терминатор. Мой вопрос в том, почему результат всегда равен 7, если strlen просто ищет '\ 0' в памяти. –
@WeissZucker Обновлен мой ответ, надеюсь, что он станет понятнее. –
Переменная p
указывает на один символ, а не на строку с нулевым завершением. Поэтому, когда вы вызываете strlen
, он пытается получить доступ к любой памяти после c
. Это вызывает undefined behavior.
Что происходит в данном конкретном случае является то, что после того, как a
в памяти есть шесть ненулевых байт следует один нулевой байт, так что вы получите 7. Вы не можете, однако, зависеть от этого поведения. Например, если вы добавите больше локальных переменных до и после a
, даже неиспользуемых, вы, вероятно, получите другой результат.
Поскольку strlen находит первый нулевой символ, начиная с принятого адреса. Вы передаете адрес только символа, поэтому strlen пытается смотреть вперёд в память до первого нулевого символа в памяти после переменной c.
В любом случае, вы не можете быть уверены в результатах, и это зависит от компилятора и всего кода, который вы написали. Более того, вы можете даже сбой памяти с исключением памяти.
Потому что 'p' не указывает на действительную строку с нулевым номером –
@George Tried, но все равно получает 7 –
' strlen() 'return type is' size_t', вы должны использовать другой формат: 'printf («% lu \ n», strlen (p)); '->' printf ("% zu \ n", strlen (p)); ' – chqrlie