易百教程

66、memcpy 和 memmove 有什么区别?

这两个副本函数都用于将 n 个字符从源对象复制到目标对象,但它们有一些区别,如下所述。

  • 如果源指针和目标指针指向的内存区域重叠,则 memcpy 复制函数会显示未定义的行为。 memmove 函数在重叠的情况下具有定义的行为。 因此,每当有疑问时,使用 memmove 代替 memcpy 会更安全。

    #include <string.h>
    #include <stdio.h>
    char str1[50] = "I am going from Delhi to Gorakhpur";
    char str2[50] = "I am going from Gorakhpur to Delhi";
    int main( void )
    {
      //Use of memmove
      printf( "Function:\tmemmove with overlap\n" );
      printf( "Orignal :\t%s\n",str1);
      printf( "Source:\t\t%s\n", str1 + 5 );
      printf( "Destination:\t%s\n", str1 + 11 );
      memmove( str1 + 11, str1 + 5, 29 );
      printf( "Result:\t\t%s\n", str1 );
      printf( "Length:\t\t%d characters\n", strlen( str1 ) );
      //Use of memcpy
      printf( "Function:\tmemcpy with overlap\n" );
      printf( "Orignal :\t%s\n",str2);
      printf( "Source:\t\t%s\n", str2 + 5 );
      printf( "Destination:\t%s\n", str2 + 11 );
      memcpy( str2 + 11, str2 + 5, 29 );
      printf( "Result:\t\t%s\n", str2 );
      printf( "Length:\t\t%d characters\n", strlen( str2 ) );
      return 0;
    }
    

    运行结果:

    Function: memmove with overlap
    Orignal : I am going from Delhi to Gorakhpur
    Source: going from Delhi to Gorakhpur
    Destination: from Delhi to Gorakhpur
    Result: I am going going from Delhi to Gorakhpur
    Length: 40 characters
    Function: memcpy with overlap
    Orignal : I am going from Gorakhpur to Delhi
    Source: going from Gorakhpur to Delhi
    Destination: from Gorakhpur to Delhi
    Result: I am going going fring frakg frako frako
    Length: 40 characters
    
  • 与 memcpy 相比,memmove 函数较慢,因为在 memmove 中,额外的临时数组用于从源复制 n 个字符,然后将存储的字符复制到目标内存。

  • memcpy 在转发副本时很有用,但 memmove 在重叠场景的情况下很有用。