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.