strlcpy: источник и назначение указывают на один и тот же объект

Я только начинаю понимать 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 ответа

Решение

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

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

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


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

Если подпись была такой, как показано ниже, чем использовать 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);

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

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

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

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

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

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

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

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

Другие вопросы по тегам