Можно ли реализовать strnlen с помощью memchr? - PullRequest
3 голосов
/ 19 января 2020

Является ли реализация strnlen, которая следует за недействительной?

size_t strnlen(const char *str, size_t maxlen)
{
    char *nul = memchr(str, '\0', maxlen);
    return nul ? (size_t)(nul - str) : maxlen;
}

Я предполагаю, что memchr всегда может смотреть на maxlen байтов независимо от содержимого этих байтов. Разрешает ли контракт strnlen просматривать все байты maxlen, только если отсутствует терминатор NUL? Если это так, размер в памяти str может быть меньше maxlen байтов, в этом случае memchr может попытаться прочитать недопустимые области памяти. Это правильно?

Ответы [ 2 ]

4 голосов
/ 19 января 2020

Да, опубликованная реализация соответствует: memchr() не должен считывать байты из str после первого вхождения '\0'.

C17 7.24.5.1. memchr функция

Синопсис

#include <string.h>
void *memchr(const void *s, int c, size_t n);

Описание

Функция memchr находит первый вхождение c (преобразуется в unsigned char) в начальные n символов (каждый интерпретируется как unsigned char) объекта, на который указывает s. Реализация должна вести себя так, как будто она читает символы последовательно и останавливается, как только найден соответствующий символ.

Возвращает

Функция memchr возвращает указатель на расположенный символ или нулевой указатель, если символ не встречается в объекте.

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

2 голосов
/ 19 января 2020

Я предполагаю, что memchr всегда может смотреть на maxlen байтов независимо от содержимого этих байтов.

Это предположение неверно. Из POSIX :

Реализации должны вести себя так, как будто они читают по байтам память от начала байтов, на которые указывает s , и останавливаются на первое вхождение c (если оно найдено в начальных n байтах).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...