strlcpy: источник и пункт назначения указывают на один и тот же объект - PullRequest
2 голосов
/ 06 марта 2020

Я только начинаю понимать strlcpy .

size_t strlcpy(char *destination, const char *source, size_t size);

Мой гипотетический вопрос: что, если пункт назначения и источник указывают на один и тот же объект?

Пример :

char destination[100];

const char*source = "text";

destination = source;

strlcpy(destination, source, sizeof(destination))

Что происходит в бэкэнде?

Знает ли strlcpy, что источник и назначение имеют один и тот же указатель?

Или

Копирует ли это вслепую и тратит ли впустую циклы процессора - копируя одинаковые байты?

Ответы [ 3 ]

1 голос
/ 07 марта 2020

Что если пункт назначения и источник указывают на один и тот же объект?

strlcpy() не является частью стандартной библиотеки C. Его точная функциональность может варьироваться от компилятора к компилятору. Просмотрите документацию конкретного компилятора / библиотеки, чтобы получить лучший ответ.

Как часть систем BSD, strlcpy (3) - Linux man page , я не нашел ничего - допускает перекрытие.


Начиная с C99, ключевое слово restrict помогает ответить на вопрос «Что если пункт назначения и источник указывают на один и тот же объект?» part.

Если подпись была такой, как указано ниже, то при использовании destination, source эта ссылка на перекрывающиеся данные будет неопределенное поведение . Может произойти что угодно.

size_t strlcpy(char * restrict destination, const char * restrict source, size_t size);

Если подпись была такой, как указано ниже, и компилятор соответствует C99 или более поздней версии, чем использование destination, source, которое может перекрываться, это определенное поведение.

Если подпись была как указано ниже, и компилятор не является жалобой для C99 или более поздней версии, чем использование destination, source, которое может перекрываться, вероятно неопределенное поведение , если документация не рассматривает этот случай.

size_t strlcpy(char * destination, const char *source, size_t size);
0 голосов
/ 07 марта 2020

Поскольку strlcpy не определено ни стандартом ISO C, ни каким-либо другим "официальным" стандартом, о котором я знаю, не обязательно канонический ответ на этот вопрос.

Ближайшая вещь Официальной спецификацией для этой функции, вероятно, является справочная страница OpenBSD , так как эта функция была представлена ​​на бумаге в соавторстве с Тео де Раадтом, создателем OpenBSD. (Первым автором статьи является Тодд C. Миллер.) На этой справочной странице написано:

Если строки sr c и dst перекрываются, поведение не определено.

В частности, вы можете видеть в источнике , что с этой конкретной реализацией, если бы вы сделали

char buf[20] = "hello world";
char *dest = buf+2;
strlcpy(dest, buf, 18);

, тогда dest в конечном итоге указывало бы на строку "heheheheheheheheh" вместо "hello world", как вы, вероятно, хотели бы.

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

0 голосов
/ 06 марта 2020

strlcpy скопирует длину буфера и обеспечит завершение строки 0. Он не проверит, что ваши dest и sr c совпадают, вы должны проверить, что указатели нацелены на один и тот же адрес. Если нет, он просто перезапишет данные и убедится, что последний байт dest равен 0.

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