Когда люди говорят: « strcpy()
Это опасно, используйте strncpy()
вместо этого» (или аналогичные утверждения о strcat()
и т. Д., Но я собираюсь использовать strcpy()
здесь в качестве основного), они имеют в виду, что нет никаких ограничений strcpy()
. Таким образом, слишком длинная строка приведет к переполнению буфера. Они правы. Использование strncpy()
в этом случае предотвратит переполнение буфера.
Я чувствую, что это strncpy()
действительно не исправляет ошибки: это решает проблему, которую может легко избежать хороший программист.
Как программист на C, вы должны знать конечный размер, прежде чем пытаться копировать строки. Это предположение strncpy()
и в strlcpy()
последних параметрах: вы указываете им этот размер. Вы также можете узнать исходный размер, прежде чем копировать строки. Затем, если пункт назначения недостаточно велик, не звонитеstrcpy()
. Либо перераспределите буфер, либо сделайте что-нибудь еще.
Почему мне не нравится strncpy()
?
strncpy()
- плохое решение в большинстве случаев: ваша строка будет усечена без какого-либо уведомления - я бы предпочел написать дополнительный код, чтобы выяснить это сам, а затем предпринять действия, которые я хочу предпринять, вместо того, чтобы позволить какой-то функции решить за мне о том, что делать.
strncpy()
очень неэффективно. Он записывает каждый байт в целевой буфер. Вам не нужны эти тысячи '\0'
в конце пункта назначения.
- Он не записывает завершение,
'\0'
если место назначения недостаточно велико. Так что вы все равно должны сделать это сами. Сложность сделать это не стоит проблем.
Теперь мы подошли к strlcpy()
. Изменения strncpy()
делают его лучше, но я не уверен, strl*
оправдывает ли конкретное поведение их существование: они слишком специфичны. Вам все равно нужно знать размер места назначения. Это более эффективно, чем strncpy()
потому, что он не обязательно записывает каждый байт в месте назначения. Но это решает проблему , которую можно решить, выполнив: *((char *)mempcpy(dst, src, n)) = 0;
.
Я не думаю, что кто-то говорит это strlcpy()
или strlcat()
может привести к проблемам с безопасностью, то, что они (и я) говорят, что они могут привести к ошибкам, например, когда вы ожидаете, что будет записана вся строка, а не ее часть.
Главный вопрос здесь: сколько байтов копировать? Программист должен знать это , и если он не делает, strncpy()
или strlcpy()
не спасет.
strlcpy()
и strlcat()
не являются стандартными, ни ISO C, ни POSIX. Поэтому их использование в переносимых программах невозможно. Фактически, strlcat()
существует два разных варианта: реализация Solaris отличается от других для крайних случаев, включающих длину 0. Это делает ее даже менее полезной, чем в противном случае.
strlcpy
иstrlcat
хотел сообщить какие - то условие ошибки , если они торкались ограничением размера буфера назначения. Хотя вы можете проверить возвращенную длину, чтобы проверить это, это не очевидно. Но я думаю, что это незначительная критика. Аргумент «они поощряют использование строк C, поэтому они плохие» - глупый.