strcpy vs. memcpy

81

Jaka jest różnica między memcpy()i strcpy()? Próbowałem go znaleźć za pomocą programu, ale oba dają ten sam wynik.

Wynik

Sachin Chourasiya
źródło

Odpowiedzi:

128

co można zrobić, aby zobaczyć ten efekt

Skompiluj i uruchom ten kod:

Spowoduje to:

Widać, że „ch” zostało skopiowane przez memcpy(), ale nie strcpy().

egrunin
źródło
1
Witam, wiem, że post jest stary, ale mam dwa pytania dotyczące go. Po pierwsze - printf("%2.2x ", *p);- dlaczego ograniczyłeś printf do 2.2? Poza tym wcale NIE widzę kropki ... Po drugie - printf("%c", *p ? *p : ' ');- co tak naprawdę sprawdza ten test? Jeśli *p? Dziękuję z góry za Twoją odpowiedź!
Peter Cerba
14
W instrukcji printf „x” oznacza „podstawę 16”. „2.2” oznacza: dwie i tylko dwie cyfry. Te *pśrodki testowe: „Jeśli trafisz null, wydrukować przestrzeni”.
egrunin
86

strcpyzatrzymuje się, gdy napotka znak NUL ( '\0'), memcpynie. Nie widać tu efektu, ponieważ %sprintf również zatrzymuje się na NUL.

Yann Ramin
źródło
2
@Sachin: Zainicjuj pi tdo czegoś (na przykład wszystkie spacje), a następnie po skopiowaniu porównaj p[3]z t[3]. strcpyNie wykracza poza to p[2], gdzie stwierdzono charakter zerową, ale memcpyjako skierowane kopiowane pięć znaków.
Cascabel
9
Minor nit-pick: strcpy zatrzymuje się, gdy napotka znak NUL (jedno „L”). NULL (dwa „L”) jest stałą czasu kompilacji dla wskaźnika, który gwarantuje, że nie będzie wskazywał żadnego prawidłowego obiektu.
Daniel Stutzbach
jeśli dest i src nakładają się, strcpy wyrzuci błąd seg?
Alcott,
12

strcpykończy się, gdy zostanie znaleziony zerowy terminator ciągu źródłowego. memcpywymaga przekazania parametru rozmiaru. W przypadku, gdy przedstawiłeś, printfinstrukcja zatrzymuje się po znalezieniu terminatora null dla obu tablic znaków, jednak znajdziesz t[3]i t[4]skopiujesz również dane w nich.

fbrereto
źródło
9

strcpy kopiuje jeden po drugim znak ze źródła do celu, aż znajdzie znak NULL lub „\ 0” w źródle.

gdzie jako memcpykopiuje dane (nie znak) ze źródła do miejsca przeznaczenia o danym rozmiarze n, niezależnie od danych w źródle.

memcpypowinno być używane, jeśli dobrze wiesz, że źródła zawierają inne elementy niż znak. w przypadku danych zaszyfrowanych lub danych binarnych memcpy jest idealnym rozwiązaniem.

strcpyjest przestarzały, więc użyj strncpy.

Viswesn
źródło
3

Ze względu na pusty znak w sciągu printfnie pokaże niczego poza tym. Różnica między pi tbędzie w postaci 4 i 5. pnie będzie miała żadnego (będą śmieci) i tbędzie miała 'c'i 'h'.

Thomas Jones-Low
źródło
2
  • Różnica w zachowaniu: strcpyzatrzymuje się, gdy napotka NULLlub'\0'
  • Różnica w wydajności: memcpyjest zwykle bardziej wydajna niż ta strcpy, która zawsze skanuje dane, które kopiuje
euccas
źródło
2

Główna różnica polega na tym, że memcpy()zawsze kopiuje dokładnie określoną liczbę bajtów; strcpy()z drugiej strony będzie kopiować, dopóki nie odczyta bajtu NUL (znanego również jako 0), a następnie zatrzyma się.

Jeremy Friesner
źródło
1

Problem z twoim programem testowym polega na tym, że printf()przestaje wstawiać argument do %s, gdy napotka zakończenie zerowe \0. Więc w swoim wyjściu prawdopodobnie nie zauważyłeś, że memcpy()skopiowałeś znaki ci hrównież.

Widziałem w GNU glibc-2.24, że (dla x86) strcpy()tylko wywołania memcpy(dest, src, strlen(src) + 1).

Jaspar L.
źródło
0

printf("%s",...) zatrzymuje drukowanie danych po napotkaniu wartości null, więc oba wyjścia są takie same.

Poniższy kod rozróżnia strcpyi memcpy:

abhijeet keshri
źródło