strcpy проти memcpy


81

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

Вихідні дані


Відповіді:


128

що можна зробити, щоб побачити цей ефект

Скомпілюйте та запустіть цей код:

Це дасть такий результат:

Ви бачите, що "ch" скопіював memcpy(), але ні strcpy().


1
Привіт, я знаю, що публікація застаріла, але у мене є два запитання щодо неї. Перше - printf("%2.2x ", *p);- чому Ви обмежили printf до 2,2? До того ж я взагалі НЕ бачу крапки ... Друге - printf("%c", *p ? *p : ' ');- що насправді перевіряє цей тест? Якщо *p? Заздалегідь дякуємо за Вашу відповідь!
Peter Cerba

14
У заяві printf "x" означає "основа 16". "2.2" означає: дві і лише дві цифри. У *pтесті означає: «якщо ви потрапили в нуль, друк пробілу» .
егрунін

86

strcpyзупиняється, коли зустрічає '\0'символ NUL ( ), memcpyні. Ви не бачите ефекту тут, оскільки %sв printf також зупиняється на NUL.


2
@Sachin: Ініціалізуйте pі tдо чогось (наприклад, усіх пробілів), а потім після копіювання порівняйте p[3]з t[3]. strcpyЧи не виходили за межі p[2], де він знайшов порожній символ, але memcpyяк відразу скопійовано п'яти символів.
Cascabel

9
Незначний вибір: strcpy зупиняється, коли він зустрічає символ NUL (один "L"). NULL (два "L") - це константа часу компіляції для вказівника, гарантовано не вказує на будь-який дійсний об'єкт.
Даніель Штуцбах

якщо dest і src перекриваються, strcpy видасть помилку сегментації?
Alcott,

12

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


9

strcpy копіює символ від джерела до пункту призначення по черзі, доки в джерелі не знайде NULL або символ \ \ 0.

де як memcpy копіює дані (не символ) з джерела до місця призначення заданого розміру n, незалежно від даних у джерелі.

memcpyслід використовувати, якщо ви добре знаєте, що джерело містить інший, ніж символ. для зашифрованих даних або двійкових даних memcpy є ідеальним способом.

strcpyзастаріло, тому використовуйте strncpy.


3

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


2
  • Різниця в поведінці: strcpyзупиняється, коли зустрічає NULLабо'\0'
  • Різниця в продуктивності: memcpyзазвичай ефективніша, ніж strcpyзавжди сканування даних, які вона копіює

2

Головна відмінність полягає в тому, що memcpy()завжди копіюється точна кількість байтів, яку ви вказали; strcpy(), з іншого боку, буде копіювати, поки не прочитає байт NUL (він же 0), а потім зупиниться після цього.


1

Проблема з вашою тестовою програмою полягає в тому, що printf()перестає вставляти аргумент %s, коли вона зустрічає нульове закінчення \0. Отже, у своєму висновку ви, напевно, не помічали, що memcpy()скопіювали символи cі hтакож.

Я бачив у GNU glibc-2.24, що (для x86) strcpy()просто дзвінки memcpy(dest, src, strlen(src) + 1).


0

printf("%s",...) зупиняє друк даних, коли зустрічається null, тому обидва виходи однакові.

Наступний код розрізняє strcpyі memcpy:

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.