Вопрос

РЕДАКТИРОВАТЬ: Я добавил источник для примера.

Я наткнулся этот пример:

char source[MAX] = "123456789";
char source1[MAX] = "123456789";
char destination[MAX] = "abcdefg";
char destination1[MAX] = "abcdefg";
char *return_string;
int index = 5;

/* This is how strcpy works */
printf("destination is originally = '%s'\n", destination);
return_string = strcpy(destination, source);
printf("after strcpy, dest becomes '%s'\n\n", destination);

/* This is how strncpy works */
printf( "destination1 is originally = '%s'\n", destination1 );
return_string = strncpy( destination1, source1, index );
printf( "After strncpy, destination1 becomes '%s'\n", destination1 );

Который произвел этот выход:

destination is originally = 'abcdefg'
After strcpy, destination becomes '123456789'

destination1 is originally = 'abcdefg'
After strncpy, destination1 becomes '12345fg'

Что заставляет меня задуматься, почему кто -то захочет этот эффект. Похоже, это было бы сбивает с толку. Эта программа заставляет меня думать, что вы можете в основном скопировать чье -то имя (например, Том Брокау) с Tom Bro763.

Каковы преимущества использования strncpy() над strcpy()?

Это было полезно?

Решение

strncpy Борьба с переполнением буфера, требуя от вас поместить в него длину. strcpy зависит от следа \0, что не всегда происходит.

Во -вторых, почему вы решили скопировать только 5 символов на 7 строке символов, но он создает ожидаемое поведение. Это только копирование на первом n персонажи, где n третий аргумент.

А n Все функции используются в качестве защитного кодирования против переполнений буфера. Пожалуйста, используйте их вместо более старых функций, таких как strcpy.

Другие советы

А strncpy() Функция была разработана с учетом очень конкретной проблемы: манипулирование строками, хранящимися в манере оригинальных записей каталога UNIX. Они использовали массив с фиксированным размером, и NUL-концевый концевой сигнал использовался только в том случае, если имя файла было короче массива.

Вот что стоит за двумя странными strncpy():

  • Он не ставит NUL-концевый терминатор в пункт назначения, если он полностью заполнен; а также
  • Он всегда полностью заполняет пункт назначения, при необходимости.

За «безопаснее strcpy()", тебе лучше использовать strncat() вот так:

if (dest_size > 0)
{
    dest[0] = '\0';
    strncat(dest, source, dest_size - 1);
}

Это всегда будет нанесено на то, чтобы получить результат, и не будет копировать больше, чем необходимо.

Хотя я знаю намерение позади strncpy, это не очень хорошая функция. Избегайте обоих. Раймонд Чен объясняет.

Лично мой вывод просто чтобы избежать strncpy И все его друзья, если вы имеете дело с строками с нулевым находом. Несмотря на «STR» в названии, эти функции не производят строки с нулевым концевым. Они преобразуют нулевую строку в необработанный буфер символов. Использование их, где ожидается строка с нулевым концевым, поскольку второй буфер просто неправильно. Мало того, что вы не можете получить надлежащее неверное прекращение, если источник слишком длинный, но если источник короткий, вы получаете ненужную нулевую прокладку.

Смотрите также Почему Strncpy небезопасен?

Strncpy не более безопасна, чем strcpy, он просто торгует один тип ошибок с другим. В C, при обращении с струнами C вам нужно знать размер ваших буферов, обойти его. strncpy был оправдан для каталога, упомянутой другими, но в противном случае вы никогда не должны его использовать:

  • Если вы знаете длину своей строки и буфера, зачем использовать strncpy? В лучшем случае это пустая трата вычислительной мощности (добавление бесполезного 0)
  • Если вы не знаете длины, то вы рискуете молча укожать свои струны, что не намного лучше, чем переполнение буфера

Вы ищете функцию strlcpy() который заканчивает всегда строку с 0 и инициализирует буфер. Он также может обнаружить переполнение. Единственная проблема, это не (действительно) портативно и присутствует только в некоторых системах (BSD, Solaris). Проблема с этой функцией заключается в том, что она открывает другую банку червей, как это видно из дискуссий наhttp://en.wikipedia.org/wiki/strlcpy

Мое личное мнение в том, что это гораздо более полезно, чем strncpy() а также strcpy(). Анкет Он имеет лучшую производительность и является хорошим компаньоном для snprintf(). Анкет Для платформ, у которых его нет, это относительно легко реализовать. (Для фазы разработки приложения я заменил эти две функции (snprintf() а также strlcpy()) с уловкой версией, которая жестоко прерывает программу на переполнениях буфера или уточнения. Это позволяет быстро поймать худших преступников. Особенно, если вы работаете над кодовой базой от кого -то другого.

РЕДАКТИРОВАТЬ: strlcpy() можно легко реализовать:

size_t strlcpy(char *dst, const char *src, size_t dstsize)
{
  size_t len = strlen(src);
  if(dstsize) {
    size_t bl = (len < dstsize-1 ? len : dstsize-1);
    ((char*)memcpy(dst, src, bl))[bl] = 0;
  }
  return len;
}

А strncpy() Функция является более безопасной: вы должны пройти максимальную длину, которую может принять буфер назначения. В противном случае может произойти, что исходная строка не завершена 0, и в этом случае strcpy() Функция может писать больше символов в назначение, развращая все, что находится в памяти после буфера назначения. Это проблема с отверстием буфера, используемая во многих эксплойтах

Также для функций POSIX API, таких как read() что не помещает завершающееся 0 в буфере, но возвращает количество прочтения байтов, вы либо вручную положите 0, либо скопируете его, используя его strncpy().

В вашем примере кода, index на самом деле не индекс, но count - Он говорит, сколько персонажей в большинстве копировать из источника в пункт назначения. Если среди первых n байтов источника нет нулевого байта, строка, помещенная в пункт назначения

strncpy заполняет место назначения ' 0' для размера источника, если размер назначения меньше ....

Манстрация:

Если длина SRC меньше n, strncpy () покладывает оставшуюся часть Dest с нулевыми байтами.

и не только остальные ... также после этого, пока не будут достигнуты символы N. И таким образом вы получаете переполнение ... (см. Реализацию страницы человека)

Это может использоваться во многих других сценариях, где вам нужно скопировать только часть вашей исходной строки в пункт назначения. Используя strncpy (), вы можете скопировать ограниченную часть исходной строки, в отличие от strcpy (). Я вижу, что вы установили код, из publib.boulder.ibm.com.

Это зависит от нашего требования. Для пользователей Windows

Мы используем strncpy всякий раз, когда не хотим копировать всю строку, или хотим скопировать только n количества символов. Но strcpy копирует всю строку, включая прекращение символа нулевого символа.

Эти ссылки помогут вам больше узнать о Strcpy и Strncpy и где мы можем использовать.

о Strcpy

о Strncpy

STRNCPY является более безопасной версией Strcpy, на самом деле, вы никогда не должны использовать STRCPY, потому что его потенциальная уязвимость буфера переполнена, что делает вас системой уязвимой для всех атак

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top