Strlen Функция поведения на одном символе
Вот мой код:
void func(char c)
{
char * ptr = &c;
size_t len = strlen(ptr);
printf("len - %d\n", len);
}
len
всегда печатается как 1.
strlen(..)
определяет длину char
массив путем нахождения нулевого символа (\0
в конце этого. Вот ptr
инициализируется только адресом одного символа (c
). c
не содержит нулевых символов. Как ptr
получить длину?
3 ответа
Вы не можете использовать strlen()
на указатель, который не указывает на массив с нулевым символом в конце. Это вызывает неопределенное поведение.
Как только ваша программа достигает UB, ничего не гарантируется.
FWIW, strlen()
возвращает тип size_t
так что вы должны использовать %zu
спецификатор формата для печати результата.
Поведение вашего кода не определено по двум причинам. Возвращает 1 случайно.
strlen
работает, начиная с указанного адреса, и увеличивая этот адрес до\0
достигнуто Это согласуется с тем, как стандартная библиотека C моделирует строки. Если вы не владеете всей памятью (как непрерывный блок) между начальным адресом и этим\0
затем входstrlen
неправильно сформированПоведение
printf
не определено из-за неверного спецификатора формата. использование%zu
заsize_t
,
с не содержит нулевых символов. Как ptr получает длину?
Это не так. Похоже, что дает правильный ответ в ваших тестах, потому что расположение памяти после адреса c
случается, содержит нулевой байт. Это местоположение не определено так, чтобы содержать ноль, и программе не разрешен доступ к нему, поэтому вы не можете рассчитывать на такой код, продолжающий работать.
На языке стандарта C поведение программы не определено, что означает, что результат операции не только непредсказуем, но и вся программа становится бессмысленной.
Даже без учета неопределенного поведения приведенный выше код может перестать работать с малейшими изменениями - например, когда вы меняете архитектуру, компилятор или даже флаги компиляции, или когда вы добавляете больше функций в микс. Хотя такие фрагменты кода могут быть полезны для изучения того, как все это работает, они никогда не должны использоваться в рабочем коде.