2016-05-14 5 views
-2

Может кто-нибудь объяснить, почему этот код:Почему эти две, казалось бы, одни и те же объявления приводят к различной длине строки?

char t1[20]; 
char t2[20]; 

memset(t1, 'B', sizeof(t1)); 
memset(t2, 'B', sizeof(t2)); 
printf("%lu\n", strlen(t1)); 
printf("%lu\n", strlen(t2)); 

результат:

22 
21 

Спасибо-х

+3

Обратите внимание, что обе длины вы получаете больше, чем фактические массивы ... не имеют нулевой символ в массивы, чтобы отметить конец строки, поэтому 'strlen()' продолжает идти, пока не найдет один (где-то рядом с концом массива). – Dmitri

+2

Потому что у вас нет нулевой строки, либо вы можете получить мусорные результаты. –

+0

не может воспроизвести проблему. – user3078414

ответ

1

strlen ожидает, что будет дано (указатель на) C строку. Строка C представляет собой массив из char, завершенный нулевым символом, '\0'.

Когда вы memset ваших char массивов, вы просто написать 'B' в каждый элемент, таким образом, ни один из этих массивов является строкой C. Передача их strlen - это неопределенное поведение.

Для того, чтобы исправить это, установите последний элемент каждого массива соответственно:

t1[19] = '\0'; 
t2[19] = '\0'; 
+0

Интересно, что разные компиляторы, похоже, по-разному реализуют 'memset'. llvm clang, кажется, помещает конечный '\ 0 ', тогда как gcc - нет. В любом случае вы сэкономите массу неприятностей, если вы «программно завершите» C-строки. – user3078414

+1

@ user3078414 Это ложное предположение: clang, безусловно, делает ** не ** ставит конечный '' \ 0''. То, что вы, скорее всего, являетесь свидетелем, представляет собой комбинацию нулевого пространства стека и некоторого выравнивания (64-битная машина?), Так что фактически есть нулевой байт ** после ** конца массивов. –

+0

Чтобы быть точным, этот «* strlen» ожидает, что ему будет присвоен (указатель на a) * C string *. * "Должен читать" * 'strlen' ожидает, что ему будет присвоен (указатель на первый элемент a) * C строка *. * " – alk

 Смежные вопросы

  • Нет связанных вопросов^_^