- 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.