memcpy () против memmove () - PullRequest
       104

memcpy () против memmove ()

146 голосов
/ 11 декабря 2010

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

Однако, когда я выполняю эти две функции на перекрывающихся блоках памяти, они оба дают одинаковый результат. Например, возьмите следующий пример MSDN на странице справки memmove(): -

Есть ли лучший пример, чтобы понять недостатки memcpy и как memmove решает это?

// crt_memcpy.c
// Illustrate overlapping copy: memmove always handles it correctly; memcpy may handle
// it correctly.

#include <memory.h>
#include <string.h>
#include <stdio.h>

char str1[7] = "aabbcc";

int main( void )
{
    printf( "The string: %s\n", str1 );
    memcpy( str1 + 2, str1, 4 );
    printf( "New string: %s\n", str1 );

    strcpy_s( str1, sizeof(str1), "aabbcc" );   // reset string

    printf( "The string: %s\n", str1 );
    memmove( str1 + 2, str1, 4 );
    printf( "New string: %s\n", str1 );
}

Выход:

The string: aabbcc
New string: aaaabb
The string: aabbcc
New string: aaaabb

Ответы [ 11 ]

0 голосов
/ 05 января 2015

Я попытался запустить ту же программу, используя eclipse, и она показывает четкую разницу между memcpy и memmove. memcpy() не заботится о перекрытии области памяти, которая приводит к повреждению данных, в то время как memmove() сначала скопирует данные во временную переменную, а затем скопирует в фактическую область памяти.

При попытке скопировать данные из местоположения str1 в str1+2, вывод memcpy равен "aaaaaa". Вопрос будет как? memcpy() будет копировать один байт за раз слева направо. Как показано в вашей программе "aabbcc", то все копирование будет происходить, как показано ниже,

  1. aabbcc -> aaabcc

  2. aaabcc -> aaaacc

  3. aaaacc -> aaaaac

  4. aaaaac -> aaaaaa

memmove() сначала скопирует данные во временную переменную, а затем скопирует в фактическую ячейку памяти.

  1. aabbcc(actual) -> aabbcc(temp)

  2. aabbcc(temp) -> aaabcc(act)

  3. aabbcc(temp) -> aaaacc(act)

  4. aabbcc(temp) -> aaaabc(act)

  5. aabbcc(temp) -> aaaabb(act)

Вывод

memcpy: aaaaaa

memmove: aaaabb

...