zoukankan      html  css  js  c++  java
  • memcpy与memmove区别

    头文件:#include <string.h>

    memmove() 用来复制内存内容,其原型为:
        void * memmove(void *dest, const void *src, size_t num);

    memmove() 与 memcpy() 类似都是用来复制 src 所指的内存内容前 num 个字节到 dest 所指的地址上。不同的是,memmove() 更为灵活,当src 和 dest 所指的内存区域重叠时,memmove() 仍然可以正确的处理,不过执行效率上会比使用 memcpy() 略慢些。

    更多介绍请参考 memcpy(),下面给出一个示例:

    1. #include <stdio.h>
    2. #include <stdlib.h>
    3. #include <string.h>
    4. int main ()
    5. {
    6. char str[] = "memmove can be very useful......";
    7. memmove (str+20,str+15,11);
    8. puts (str);
    9. system("pause");
    10. return 0;
    11. }

    运行结果:
    memmove can be very very useful.

    这段代码能够很好的说明内存重叠时的情况:先将内容复制到类似缓冲区的地方,再用缓冲区中的内容覆盖 dest 指向的内存,请看下图。

     
     
     

    Memcopy和memmove函数在linux下看了一下两个函数的源码。

    两个函数都在头文件string.h中定义,函数原型为:

    void * __cdecl memcpy ( void * dst,const void * src,size_t count);

    void * __cdecl memmove ( void * dst,const void * src,size_t count);

    实现代码如下:

    void * __cdecl memcpy ( void * dst,const void * src,size_t count)

    {

             void * ret = dst;

             while (count--)

             { // 注意, memcpy函数没有处理dst和src区域是否重叠的问题

                       *(char *)dst = *(char *)src;

                       dst = (char *)dst + 1;

                       src = (char *)src + 1;

             }

             return(ret);

    }

    void * __cdecl memmove ( void * dst,const void * src,size_t count)

    {

             void * ret = dst;

             if (dst <= src || (char *)dst >= ((char *)src + count))

             {

                       // 若dst和src区域没有重叠,则从起始处开始逐一拷贝

                       while (count--)

                       {

                                *(char *)dst = *(char *)src;

                                dst = (char *)dst + 1;

                                src = (char *)src + 1;

                       }

             }

             else

             { // 若dst和src 区域交叉,则从尾部开始向起始位置拷贝,这样可以避免数据冲突

                       dst = (char *)dst + count - 1;

                       src = (char *)src + count - 1;

                       while (count--)

                       {

                                *(char *)dst = *(char *)src;

                                dst = (char *)dst - 1;

                                src = (char *)src - 1;

                       }

             }

             return(ret);

    }

    总结一下:

    当src和dst区域没有重叠时,两个函数是完全一样的。木有重叠的条件是: dst <= src || (char *)dst >= ((char *)src + count 。否则,memcpy是不能正常工作的,memmove是可以正常工作的。

  • 相关阅读:
    什么是webview
    juqery.fn.extend和jquery.extend
    LeetCode
    5. Longest Palindromic Substring
    42. Trapping Rain Water
    11. Container With Most Water
    621. Task Scheduler
    49. Group Anagrams
    739. Daily Temperatures
    3. Longest Substring Without Repeating Characters
  • 原文地址:https://www.cnblogs.com/taek/p/4616454.html
Copyright © 2011-2022 走看看