Подтвердить что ты не робот

Strcpy vs. memcpy

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

int main()
{
    char s[5]={'s','a','\0','c','h'};
    char p[5];
    char t[5];
    strcpy(p,s);
    memcpy(t,s,5);
    printf("sachin p is [%s], t is [%s]",p,t);
    return 0;
}

Выход

sachin p is [sa], t is [sa]
4b9b3361

Ответ 1

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

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

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

Ответ 2

strcpy останавливается, когда встречается символ NUL ('\0'), memcpy - нет. Вы не видите здесь эффекта, так как %s в printf также останавливается на NUL.

Ответ 3

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

Ответ 4

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

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

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

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

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

Ответ 5

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

Ответ 6

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

Ответ 7

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

Ответ 8

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

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