memcpy和memmove的区别

来源:互联网 发布:降低媒体音量软件 编辑:程序博客网 时间:2024/05/19 16:28

前几天面试,华为的一个技术人员问我一个问题:memcpy和memmove有什么区别?

当时,我没回答上来。我只知道它们的入参和返回值是一样的,区别还不是很清楚,说不上来,我说可能效率不太一样吧。


其实,这两个函数的效率几乎是一样的,区别只是在于内存重叠时,memcpy不能保证拷贝的正确,而memmove却能保证拷贝的正确性。换句话说,memcpy是memmove的子集,memmove更安全。


看一下memcpy的源码:

void *memcpy(void *dest, const void *src, size_t n){const char *s = src;char *d = dest;while (n--)*d++ = *s++;return dest;}


再看一下memmove的源码:

void *memmove(void *dest, const void *src, size_t n){const char *s = src;char *d = dest;if (d <= s) {while (n--)*d++ = *s++;} else {d += n;s += n;while (n--)*--d = *--s;}return dest;}

举个简单的例子:


例如 char arr[] = "abcdefghigklmn";

memcpy(arr+2,arr,5);     结果为:arr = "abababahigklmn";

memmove(arr+2,arr,5); 结果为:arr = "ababcdehigklmn";


但是:

如果是

memcpy(arr,arr+2,5);

memmove(arr,arr+2,5);

则结果都为:arr = "cdefgfghigklmn";


总结一下就是:memcpy是从低地址往高开始拷贝,当dest <= src 时,则两个结果是一样的。而当dest > src时,则memcpy会发生内存重叠,出现拷贝错误。在memmove中,函数会先判断是否dest <= src,当小于时,则执行memcpy,否则,则从高地址向低地址拷贝,防止出现内存重叠发生拷贝错误。


其实,无论在memcpy或memmove,如果都从高地址向低地址拷贝,则都不会出现拷贝错误。所以,memmove没有必要做一个if-else判断,代码非要这样写,可能是展现一下memmove的思路吧,增强可读性吧。


综上,memmove比memcpy更安全,用memcpy的时候,必须考虑区域重叠问题,另外还要考虑缓冲区溢出问题。






原创粉丝点击