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]
Ответы
Ответ 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)
.