头文件:#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是可以正常工作的。

memcpy与memmove区别的更多相关文章

  1. [整理]内存重叠之memcpy、memmove

    函数原型: void *memcpy( void *dest, const void *src, size_t count ); void *memmove( void* dest, const vo ...

  2. memcpy与memmove的区别

    在面试中经常会被问道memcpy与memove有什么区别? 整理如下: 其实主要在考C的关键字:restrict C库中有两个函数可以从一个位置把字节复制到另一个位置.在C99标准下,它们的原型如下: ...

  3. C的memset,memcpy,strcpy 的区别 及memset memcpy memmove源码

    extern void *memcpy(void *dest,void *src,unsigned int count);#include <string.h>   功能:由src所指内存 ...

  4. 【VS开发】【C/C++开发】memcpy和memmove的区别

    memcpy和memmove()都是C语言中的库函数,在头文件string.h中,作用是拷贝一定长度的内存的内容,原型分别如下: void *memcpy(void *dst, const void ...

  5. memmove和memcpy函数的区别及实现

    一.memmove()和memcpy()函数和strcpy()函数的区别: (1)使用的类型不同,strcpy()函数只对字符串进行操作:memmove()和memcpy()函数对所有类型都适用,为内 ...

  6. memcpy memmove区别和实现

    memcpy与memmove的目的都是将N个字节的源内存地址的内容拷贝到目标内存地址中. 但当源内存和目标内存存在重叠时,memcpy会出现错误,而memmove能正确地实施拷贝,但这也增加了一点点开 ...

  7. C语言标准库函数memcpy和memmove的区别以及内存重叠问题处理

    ①memcpy()和memmove()都是C语言中的标准库函数,定义在头文件string.h中,作用是拷贝一定长度的内存的内容,原型分别如下: void *memcpy(void *dst, cons ...

  8. memcpy、memmove、memset及strcpy函数实现和理解

    memcpy.memmove.memset及strcpy函数实现和理解 关于memcpy memcpy是C和C++ 中的内存拷贝函数,在C中所需的头文件是#include<string.h> ...

  9. 关于memcpy和memmove的一点说明

    今天看到书上降到memcpy和memmove的区别才突然发现原来两者之间有如此区别,以前只知道这两个函数是 实现同样的功能,没有接触到其不同. memcpy和memmove在MSDN的定义如下: 从两 ...

随机推荐

  1. Linux 服务器如何修改 DNS

    个人一直用的阿里云的ECS,在配置环境的时候就想着修改一下默认的 DNS,听说阿里云自己的 DNS 速度和稳定性都不错,所以就将默认的 DNS 修改成了阿里云的DNS,并一直稳定使用,下面给出修改方法 ...

  2. php 时间转化总结

    iQuery插件datepicker获取的时间函数为"月月/天天/年年年年"(以04/21/2015为例)的形式 (1)转化为2015-21-04形式:$start = date( ...

  3. max_size, capacity and size 的区别

    The max_size() function returns the maximum number of elements that the container can hold. The max_ ...

  4. Linux进程间通信IPC学习笔记之有名管道

    基础知识: 有名管道,FIFO先进先出,它是一个单向(半双工)的数据流,不同于管道的是:是最初的Unix IPC形式,可追溯到1973年的Unix第3版.使用其应注意两点: 1)有一个与路径名关联的名 ...

  5. WPF 概述

    WPF 全称是:Windows Presentation Foundation,直译为Windows表示基础.WPF是专门为GUI(Graphic User Interface)程序开发设计的. 在过 ...

  6. PAT乙级真题1005. 继续(3n+1)猜想 (25)(解题)

    原题: 卡拉兹(Callatz)猜想已经在1001中给出了描述.在这个题目里,情况稍微有些复杂. 当我们验证卡拉兹猜想的时候,为了避免重复计算,可以记录下递推过程中遇到的每一个数.例如对n=3进行验证 ...

  7. Kinetic使用注意点--layer

    new Layer(config) 参数: config:包含所有配置项的对象. { clearBeforeDraw: "是否在绘图之前清空画板,默认为true", x: &quo ...

  8. windows环境下装node.js,npm,express

    windows下安装跟mac环境安装(戳我戳我戳我)大同小异. 1. 下载node.js for Mac 地址: http://nodejs.org/download/ 注意看自己系统是32位还是64 ...

  9. Many To one 多对一

    一.创建实体类:多方存一方的对象.set/get 二.编写对象的xml文件 别忘记在confg.xml映射! 三.编写接口 四.方法测试

  10. 【linux程序设计4th】第三章1

    makefile .PHONY:clean all CC=gcc CFLAGS=-Wall -g ###replace your bin BIN=simple_write simple_read co ...