strcpy против memcpy - PullRequest
66 голосов
/ 24 мая 2010

В чем разница между memcpy() и strcpy()?Я пытался найти его с помощью программы, но оба выдают одинаковый вывод.

Ответы [ 8 ]

107 голосов
/ 25 мая 2010

что можно сделать, чтобы увидеть этот эффект

Скомпилируйте и запустите этот код:

void dump5(char *str);

int main()
{
    char s[5]={'s','a','\0','c','h'};

    char membuff[5]; 
    char strbuff[5];
    memset(membuff, 0, 5); // init both buffers to nulls
    memset(strbuff, 0, 5);

    strcpy(strbuff,s);
    memcpy(membuff,s,5);

    dump5(membuff); // show what happened
    dump5(strbuff);

    return 0;
}

void dump5(char *str)
{
    char *p = str;
    for (int n = 0; n < 5; ++n)
    {
        printf("%2.2x ", *p);
        ++p;
    }

    printf("\t");

    p = str;
    for (int n = 0; n < 5; ++n)
    {
        printf("%c", *p ? *p : ' ');
        ++p;
    }

    printf("\n", str);
}

Он выдаст такой вывод:

73 61 00 63 68  sa ch
73 61 00 00 00  sa

Вы видите, что "ch" был скопирован memcpy(), но не strcpy().

66 голосов
/ 24 мая 2010

strcpy останавливается, когда встречает NULL, memcpy - нет.Вы не видите здесь эффекта, так как %s в printf также останавливается на NULL.

12 голосов
/ 24 мая 2010

strcpy завершается, когда найден нулевой терминатор исходной строки. memcpy требует передачи параметра размера. В том случае, если вы представили, что оператор printf останавливается после того, как для обоих массивов символов найден нулевой терминатор, однако вы обнаружите, что t[3] и t[4] также скопировали данные в них.

9 голосов
/ 05 декабря 2012

strcpy копирует символы из источника в место назначения по одному, пока не найдет NULL или символ '\ 0' в источнике.

while((*dst++) = (*src++));

где as memcpy копирует данные (не символьные) из источника в место назначения с заданным размером n независимо от данных в источнике.

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

strcpy устарело, поэтому используйте strncpy.

3 голосов
/ 24 мая 2010

Из-за нулевого символа в вашей строке s, printf не будет ничего показывать. Разница между p и t будет заключена в символы 4 и 5. p не будет иметь (они будут мусором), а t будет иметь 'c' и 'h'.

2 голосов
/ 19 января 2017
  • Разница в поведении: strcpy останавливается, когда встречает NULL или '\0'
  • Разница в производительности: memcpy обычно более эффективен, чем strcpy, который всегда сканирует данные, которые копирует
2 голосов
/ 24 мая 2010

Основное отличие состоит в том, что memcpy() всегда копирует точное количество байтов, которое вы укажете; strcpy(), с другой стороны, будет копировать, пока не будет прочитан байт NUL (он же 0), а затем остановится после этого.

0 голосов
/ 16 февраля 2018

Проблема с вашей тестовой программой заключается в том, что printf() прекращает вставку аргумента в %s, когда он встречает нулевое завершение \0.Таким образом, в своем выводе вы, вероятно, не заметили, что memcpy() скопировал символы c и h.

Я видел в GNU glibc-2.24, что (для x86) strcpy()просто звонит memcpy(dest, src, strlen(src) + 1).

...