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


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


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.


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.


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.


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'.


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

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ę.


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


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:

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.