Chinaunix首页 | 论坛 | 博客
  • 博客访问: 813932
  • 博文数量: 157
  • 博客积分: 542
  • 博客等级: 中士
  • 技术积分: 1696
  • 用 户 组: 普通用户
  • 注册时间: 2011-11-21 20:21
文章分类
文章存档

2017年(1)

2016年(2)

2015年(6)

2014年(42)

2013年(77)

2012年(19)

2011年(10)

分类: C/C++

2013-11-01 11:26:07

函数原型:

void *memcpy(void *dest, const void *src, size_t n)

void *memmove(void *dest, const void *src, size_t n)

最近在项目中,郁白在review代码时,建议将memcpy改为memmove,虽然memcpy在我现在的使用场景不会出现问题,但是用memmove总是安全的。记得面试时,日照也问过我这个问题。

两者的功能基本相同,唯一不同的是,当 dest 和 src 有重叠的时候选用不同的函数可能会造成不同的结果。

memcpy的原理是从src的低地址开始到高地址,单个字节复制,如果src与dest有重叠,并行src的地址低于dest的话,将会得不到想要的结果,如果src的址高于dest的话,则不会出现这种情况:

实例:

1 #include 

2 #include 

3

4 using namespace std;

5

6 int main(void)

7 {

8   int i = 0;

9   int a[10];

10

11   //init

12   for (; i < 10; i ++)

13   {

14     a[i] = i;

15   }

16   //copy

17   memcpy(&a[4], a, sizeof(int) * 6);

18   //output

19   for (i = 0; i < 10; i ++)

20   {

21     cout<<”a["<

22   }

23   return 0;

24 }

输出结果为:

a[0]:0

a[1]:1

a[2]:2

a[3]:3

a[4]:0

a[5]:1

a[6]:2

a[7]:3

a[8]:0

a[9]:1

将第17行改为memmove(&a[4], a, sizeof(int) * 6),结果如下:

a[0]:0

a[1]:1

a[2]:2

a[3]:3

a[4]:0

a[5]:1

a[6]:2

a[7]:3

a[8]:4

a[9]:5

看一下memcpy与memmove的实现

代码:

void* memcpy(void* dest, void* source, size_t count)

{

void* ret = dest;

//memcpy只是简单的字节copy,没有处理重叠的情况

while (count–)

*dest++ = *source;

return ret;

}

 

void* memmove(void* dest, void* source, size_t count)

{

void* ret = dest;

if (dest <= source || dest >= (source + count))

{

//如果没有重叠或是有重叠重目标地址低于源地址

//从低地址开始复制

while (count –)

*dest++ = *source++;

}

else

{

//有果有重叠且目标地址高于源地址, 这里是高于源地址,不包括等于,有重叠即说明是在中间

//从高地址开始复制

dest += count - 1;

source += count - 1;

while (count–)

*dest– = *source–;

}

return ret;

}

阅读(581) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~