2017-01-18 18 views
0

Код C:Почему я получаю длину 7, когда применяю strlen() к указателю на один символ?

char c = 'a'; 
char *p = &c; 
printf("%lu\n",strlen(p)); 

И я получаю результат 7, и я понятия не имею, как это 7 выйти.

+3

Потому что 'p' не указывает на действительную строку с нулевым номером –

+0

@George Tried, но все равно получает 7 –

+0

' strlen() 'return type is' size_t', вы должны использовать другой формат: 'printf («% lu \ n», strlen (p)); '->' printf ("% zu \ n", strlen (p)); ' – chqrlie

ответ

1

Помните, что строки в C действительно называются байт-строки с нулевым завершением. Все строки заканчиваются одним символом '\0', что означает, что односимвольная строка на самом деле равна . Два символа: один символ плюс терминатор.

Если у вас есть указатель, указывающий на код c, у вас нет двух символов, только для одиночных символов, содержащихся в c. Вы не знаете, есть ли терминатор после этого символа в памяти, поэтому, когда strlen ищет этот терминатор, он передаст персонажа и выйдет в память, не принадлежащую какой-либо строке, чтобы искать его, и у вас будет неопределенное поведение .


попробовать проиллюстрировать то, что у вас есть, посмотрите на этот «графический» представление:

 
+---+  +-----+---------------------- 
| p | --> | 'a' | indeterminate data... 
+---+  +-----+---------------------- 

Это в основном, как она выглядит в памяти. Переменная p указывает на место, где хранится ваш символ, но после этого в памяти находятся только неопределенные данные. Это будет казаться случайным, и вы не можете определить, где будет байт, соответствующий символу терминатора строк.

Невозможно сказать, почему strlen получает значение 7, за исключением того, что он обнаруживает шесть бесконечных байтов в неопределенных данных после вашего символа. В следующий раз, когда вы запустите его, или если вы запустите его в другой системе, вы можете получить совершенно другой результат.

+0

Да, я знаю, что strlen будет искать терминатор. Мой вопрос в том, почему результат всегда равен 7, если strlen просто ищет '\ 0' в памяти. –

+0

@WeissZucker Обновлен мой ответ, надеюсь, что он станет понятнее. –

2

Переменная p указывает на один символ, а не на строку с нулевым завершением. Поэтому, когда вы вызываете strlen, он пытается получить доступ к любой памяти после c. Это вызывает undefined behavior.

Что происходит в данном конкретном случае является то, что после того, как a в памяти есть шесть ненулевых байт следует один нулевой байт, так что вы получите 7. Вы не можете, однако, зависеть от этого поведения. Например, если вы добавите больше локальных переменных до и после a, даже неиспользуемых, вы, вероятно, получите другой результат.

0

Поскольку strlen находит первый нулевой символ, начиная с принятого адреса. Вы передаете адрес только символа, поэтому strlen пытается смотреть вперёд в память до первого нулевого символа в памяти после переменной c.

В любом случае, вы не можете быть уверены в результатах, и это зависит от компилятора и всего кода, который вы написали. Более того, вы можете даже сбой памяти с исключением памяти.