写一个函数,完成内存之间的拷贝

  1. void* mymemcpy( void *dest, const void *src, size_t count )
  2. {
  3. char* pdest = static_cast<char*>( dest );
  4. const char* psrc = static_cast<const char*>( src );
  5. if( pdest>psrc && pdest<psrc+cout ) 能考虑到这种情况就行了
  6. {
  7. for( size_t i=count-1; i!=-1; --i )
  8. pdest[i] = psrc[i];
  9. }
  10. else
  11. {
  12. for( size_t i=0; i<count; ++i )
  13. pdest[i] = psrc[i];
  14. }
  15. return dest;
原型:extern void *memmove(void *dest, const void *src, unsigned int count);

  用法:#include <string.h>

  功能:由src所指内存区域复制count个字节到dest所指内存区域。

  说明:src和dest所指内存区域可以重叠,但复制后src内容会被更改。函数返回指向dest的指针。

memmove和memcpy的区别:

1.memmove

函数原型:void *memmove(void *dest, const void *source, size_t count)

返回值说明:返回指向dest的void *指针

参数说明:dest,source分别为目标串和源串的首地址。count为要移动的字符的个数

函数说明:memmove用于从source拷贝count个字符到dest,如果目标区域和源区域有重叠的话,memmove能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中。

2.memcpy

函数原型:void *memcpy(void *dest, const void *source, size_t count);

返回值说明:返回指向dest的void *指针

函数说明:memcpy功能和memmove相同,但是memcpy中dest和source中的区域不能重叠,否则会出现未知结果。

3.两者区别

函数memcpy()   从source  指向的区域向dest指向的区域复制count个字符,如果两数组重叠,不定义该函数的行为。  
  而memmove(),如果两函数重叠,赋值仍正确进行。

memcpy函数假设要复制的内存区域不存在重叠,如果你能确保你进行复制操作的的内存区域没有任何重叠,可以直接用memcpy;  
  如果你不能保证是否有重叠,为了确保复制的正确性,你必须用memmove。

memcpy的效率会比memmove高一些,如果还不明白的话可以看一些两者的实现:

  1. void *memmove(void *dest, const void *source, size_t count)
  2. {
  3. assert((NULL != dest) && (NULL != source));
  4. char *tmp_source, *tmp_dest;
  5. tmp_source = (char *)source;
  6. tmp_dest = (char *)dest;
  7. if((dest + count<source) || (source + count) <dest))
  8. {// 如果没有重叠区域
  9. while(count--)
  10. *tmp_dest++ = *tmp_source++;
  11. }
  12. else
  13. { //如果有重叠
  14. tmp_source += count - 1;
  15. tmp_dest += count - 1;
  16. while(count--)
  17. *--tmp_dest = *--tmp;
  18. }
  19. return dest;
  20. }
  1. void *memcpy(void *dest, const void *source, size_t count)
  2. {
  3. assert((NULL != dest) && (NULL != source));
  4. char *tmp_dest = (char *)dest;
  5. char *tmp_source = (char *)source;
  6. while(count --)//不对是否存在重叠区域进行判断
  7. *tmp_dest ++ = *tmp_source ++;
  8. return dest;
  9. }
memcpy()和memmove()都是C语言中的库函数,在头文件string.h中,其原型分别如下:

 

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

 
它们都是从src所指向的内存中复制count个字节到dst所指内存中,并返回dst的值。当源内存区域和目标内存区域无交叉时,两者的结果是一样的,但如果有交叉呢?先看下图:
 

图的上半部分为源内存区域在目标内存区域右边,下半部分为源内存区域在目标区域左边,源内存区域和目标内存区域都有交叉。

memcpy()是从src的起始部分开始复制,所以虽然第一种情况下没有问题,但如果遇到第二种情况,则会发生错误,如图所示,后两个字节在被复制前已经被覆盖掉了。而memmove()则由于采用了不同的复制机制,所以可以正确处理第二种情况。

memmove函数的更多相关文章

  1. 实现memmove函数

    分析:memmove函数是<string.h>的标准函数,其作用是把从source开始的num个字符拷贝到destination.最简单的方法是直接复制,但是由于它们可能存在内存的重叠区, ...

  2. strcpy函数;memcpy函数;memmove函数

    strcpy函数实现: char* strcpy(char* des,const char* source) { char* r=des; assert((des != NULL) && ...

  3. 面试题之实现系统函数系列一:实现memmove函数

    编译环境 本系列文章所提供的算法均在以下环境下编译通过. [算法编译环境]Federa 8,linux 2.6.35.6-45.fc14.i686 [处理器] Intel(R) Core(TM)2 Q ...

  4. 【C语言】模拟实现memmove函数(考虑内存重叠)

    //模拟实现memmove函数(考虑内存重叠) #include <stdio.h> #include <assert.h> #include <string.h> ...

  5. C语言memcpy()函数和memmove()函数

    C语言memcpy()函数和memmove()函数 关于 memcpy() 函数,请先看链接. memcpy() 函数和 memmove() 函数的函数原型如下: void* memcpy(void ...

  6. [转]memmove函数

    [FROM MSDN && 百科] 原型:  void *memmove( void* dest, const void* src, size_tcount ); #include&l ...

  7. 一些关于memcpy memmove函数的区别,和模拟实现

    memcpy: 它是c和c++使用的内存拷贝函数,memcpy函数的功能是从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中. 函数原型:void* memcp ...

  8. strcpy和memcpy,memmove函数的区别

    strcpy和memcpy的区别 strcpy和memcpy都是标准C库函数,它们有下面的特点. strcpy提供了字符串的复制.即strcpy只用于字符串复制,并且它不仅复制字符串内容之外,还会复制 ...

  9. C语言memmove()函数: 复制内存内容(可以重叠的内存块)

    头文件:#include <string.h> memmove() 用来复制内存内容,其原型为: void * memmove(void *dest, const void *src, s ...

随机推荐

  1. Linux如何修改文件/文件夹内所有文件的权限

    一.修改文件权限 修改文件权限前,需要了解一下权限中的”rwx”与数字的对应关系,其中r=4,w=2,x=1. 例如:”drwxr-xr-x”,第一个”d”是代表文件夹,这里不用考虑,后面九个字符,每 ...

  2. P1011 传纸条//dp优化改进状态表示

    P1011 传纸条 时间: 1000ms / 空间: 131072KiB / Java类名: Main 背景 NOIP2008复赛提高组第三题 描述 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不 ...

  3. cojs EX_香蕉 题解报告

    这道题目是香蕉的加强版 当m=100w时矩阵会很大,而且又有多组询问,所以这道题用原来香蕉的程序会T 所以我们需要更好点的做法 我们考虑优化我们的状态 首先考虑这道题的隐藏性质,考虑不合法的情况 那么 ...

  4. 【mongoDB中级篇①】游标cursor

    简述 通俗的说,游标不是查询结果,可以理解为数据在遍历过程中的内部指针,其返回的是一个资源,或者说数据读取接口. 客户端通过对游标进行一些设置就能对查询结果进行有效地控制,如可以限制查询得到的结果数量 ...

  5. AC题目简解-线段树

    线段树: http://www.notonlysuccess.com/index.php/segment-tree-complete/鉴于notonlysuccess大牛的博客对于题目的思路写的很简陋 ...

  6. PL/SQL-Thread creation error:存储空间不足,无法处理此命令

    PL/SQL中执行SQL语句,提示“Thread creation error:存储空间不足,无法处理此命令”.查找了解决方案,如下: 1. 单击开始,然后单击运行. 2. 键入 regedit,然后 ...

  7. Android Handler之Message传递参数

    最近发现Message,发送消息可以传递参数,这个思路很好,所以写了一个例子,点击屏幕,给Activity发送一个消息,传递两个参数,并把这个activity销毁掉! 程序打开界面: 点击屏幕,销毁a ...

  8. OSI七层协议

  9. Lua for windows中SciTe开启支持python的方法

    打开Options-Open Global Options #import python的#去掉即可

  10. IIS 无法打开页面,只能重启的问题

    最终解决方案: 要变通解决此问题,启用 EnableAggressiveMemoryUsage 注册表项在注册表中.当启用了 EnableAggressiveMemoryUsage 注册表项 Http ...