- Strncpy
-
strncpy
strncpy — функция стандартной библиотеки языка программирования Си, для копирования содержимого нуль-терминированной строки в буфер ограниченного размера.
Функция
strncpy
аналогичнаstrcpy
с защитой от переполнения буфера, однако не является полностью безопасной.Функция поддерживается всеми компиляторами Си.
Содержание
Функция
Прототип, описанный в заголовочном файле
string.h
:char *strncpy (char *dst, const char *src, size_t len);
dst
— указатель на буфер назначения.src
— указатель на исходную строку.len
— максимальное количество копируемых символов (см. раздел Безопасность ниже).
Функция копирует из строки
src
в буферdst
не более чемlen
символов (включая нулевой символ), не гарантируя завершения строки нулевым символом (если длина строкиsrc
больше или равнаlen
). Если длина строкиsrc
меньшеlen
, то буфер добивается доlen
нулями.Возвращаемое значение
Функция возвращает значение
dst
.Пример использования
#include <string.h> #include <stdio.h> /* для printf() */ int main() { char *str = "образец строки"; char buf[10]; // буфер размером меньше строки memset(buf, 0, sizeof(buf)); // очистка буфера, для вывода и обнуления последнего байта printf("строка: \"%s\"\n\n", str); printf("буфер перед копированием: \"%s\"\n", buf); strncpy(buf, str, sizeof(buf) - 1); // len на 1 меньше размера буфера printf("буфер после копирования: \"%s\"\n", buf); return 0; }
Вывод:
строка: "образец строки" буфер перед копированием: "" буфер после копирования: "образец с"
(строка при копировании была урезана до размера буфера — 9 символов + нулевой)
Безопасность
Функция
strncpy
призвана защитить программы от переполнения буфера, но, к сожалению, сама она также небезопасна (по стандарту) — функция не гарантирует установку нулевого символа в конец буфера, что, при попытке печати строки из буфера (или работы с ней) может привести к чтению данных за пределами буфера, которое приведет к аварийному завершению программы, что можно использовать для проведения сетевой DoS-атаки.При правильной работе с функцией, нужно предварительно обнулять последний байт буфера, и указывать функции значение
len
на единицу меньше размера буфера:char buf[BUFSIZ]; strncpy(buf, input, sizeof(buf) - 1); buf[sizeof(buf) - 1] = '\0';
Разработчики OpenBSD сделали на замену
strncpy
, нестандарную функциюstrlcpy
, гарантирующую завершение строки нулевым символом. В системах, в которых она также реализована, рекомендуется использовать ее, а неstrncpy
. В иных системах, возможна кустарная реализация этой функции, из исходного кода, распространяемого по лицензии BSD.Кроме того,
strlcpy
, также, решает проблему производительностиstrncpy
(см. далее).Проблема производительности
Стандартное поведение
strncpy
неоптимально — функция всякий раз заполняет нулями остаток буфера, что приводит к непроизводительному расходу процессорного ресурса при буфере большого размера и короткими строками (обычная ситуация в сетевых серверах).Использование вместо
strncpy
нестандартной функцииstrlcpy
или кустарной функции (как, например, в свое время был переписан Apache [1]), может обеспечить существенный прирост производительности (на синтетическом тесте был показан пятикратный прирост [2]).Внешние ссылки
- strncpy(1) (англ.) — Описание функции
strncpy
на сайте OpenBSD
Wikimedia Foundation. 2010.