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 = "sample string";
char buf[10] = {0}; // буфер размером меньше строки, инициализированный нулями
printf("строка: \"%s\"\n\n", str);
printf("буфер перед копированием: \"%s\"\n", buf);
strncpy(buf, str, sizeof(buf) - 1); // len на 1 меньше размера буфера
printf("буфер после копирования: \"%s\"\n", buf);
return 0;
}
Вывод:
строка: "sample string" буфер перед копированием: "" буфер после копирования: "sample st"
(строка при копировании была урезана до размера буфера — 9 символов + нулевой)
Безопасность
Функция strncpy призвана защитить программы от переполнения буфера, но сама она также небезопасна по дизайну — функция по стандарту не гарантирует установку нулевого символа в конец буфера, что, при попытке печати строки из буфера (или работы с ней) может привести к чтению данных за пределами буфера, которое приведет к аварийному завершению программы, что можно использовать для проведения сетевой DoS-атаки.
При правильной работе с функцией, нужно передавать в функцию значение len на единицу меньше размера буфера, а также самостоятельно устанавливать последний байт в 0:
char buf[BUFSIZE]; strncpy(buf, input, sizeof(buf) - 1); buf[sizeof(buf) - 1] = '\0';
Разработчики OpenBSD на замену strncpy сделали функцию strlcpy, стандартизованную в POSIX 1003.1-2024, гарантирующую завершение строки нулевым символом. В системах, в которых она также реализована, рекомендуется использовать её, а не strncpy. В иных системах, возможна кустарная реализация этой функции, из исходного кода, распространяемого по лицензии BSD.
Кроме того, strlcpy, также, решает проблему производительности strncpy (см. далее).
Проблема производительности
Стандартное поведение strncpy неоптимально — если строка-источник короче чем len, функция всякий раз заполняет нулями весь остаток буфера до len[1][2], что приводит к непроизводительному расходу процессорного ресурса при буфере большого размера и работе с короткими строками (обычная ситуация в сетевых серверах).
Использование вместо strncpy функции strlcpy или кустарной функции (как, например, в своё время был переписан Apache [1]), может обеспечить существенный прирост производительности (на синтетическом тесте был показан пятикратный прирост [2]).
Внешние ссылки
- strncpy(1) (англ.) — Описание функции
strncpyна сайте OpenBSD
Примечания
- ↑ the performance implications of strncpy | Nathan's Blog. Дата обращения: 17 октября 2014. Архивировано 18 октября 2014 года.
- ↑ 5.4 Copying and Concatenation Архивировано 21 октября 2014 года. // GNU Libc manual: "Using strncpy .. can also make your program much slower in one common case: copying a string which is probably small into a potentially large buffer. In this case, size may be large, and when it is, strncpy will waste a considerable amount of time copying null characters."
Content Disclaimer
Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.
- The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
- There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
- It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
- Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
- Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.