[荐]memcpy、memmove、strcpy的区别?

来源:互联网 发布:python中的生成器 编辑:程序博客网 时间:2024/05/17 00:13

【更新说明】2012-3-13

1 函数原型及用法

(1) memcpy

【函数原型】

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

C99原型:

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

【解析】

memcpy用于内存拷贝,在执行操作时,如果src和dst的地址重叠,拷贝会发生错误。C99中引入关键字restrict 进行了内存访问限制。

(2) memmove

【函数原型】

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

memmove,顾名思义就好像内存发生了搬移,由src搬移到dst地址上。搬移过程中,好像先将src搬移到一个temp的地址,再将temp搬移到dst。如果src和dst的地址重叠,也不会发生错误。但执行的效率比memcpy低。

(3) strcpy

【函数原型】

char *(const char *dst, const char *src);

【解析】

strcpy只能用于字符串(const char *)拷贝,而memxxx无此限制,可以处理包括NUL('\0')在内的任意字节。返回值是第1个参数的一份拷贝,即一个指向目标字符数组的指针。

2 关键字restrict

提到memcpy和memmove就不能不说关键字restrict ,注意到memcpy中加了restrict ,而memmove中则没有。加上restrict 关键字后,表示指针是相应数据的唯一访问方式。因此,memcpy中dst和src指针都是相应数据的唯一访问方式,这就决定了两个内存地址不能重叠。而memmove中因为move时开辟了临时空间,无此限制。

注意strcpy原型也无关键字restrict 限制,因此复制的过程中,src和dst也可能存在内存重叠现象。

【增-2012.3.13】3 Linux-2.6.23源码分析

(1) memcpy

Linux-2.6.23/lib/string.h(Line516-536)#ifndef __HAVE_ARCH_MEMCPY/** * memcpy - Copy one area of memory to another * @dest: Where to copy to * @src: Where to copy from * @count: The size of the area. * * You should not use this function to access IO space, use memcpy_toio() * or memcpy_fromio() instead. */void *memcpy(void *dest, const void *src, size_t count){char *tmp = dest;const char *s = src;while (count--)*tmp++ = *s++;return dest;}EXPORT_SYMBOL(memcpy);#endif

(2) memmove

Linux-2.6.23/lib/string.h(Line536-568)#ifndef __HAVE_ARCH_MEMMOVE/** * memmove - Copy one area of memory to another * @dest: Where to copy to * @src: Where to copy from * @count: The size of the area. * * Unlike memcpy(), memmove() copes with overlapping areas. */void *memmove(void *dest, const void *src, size_t count){char *tmp;const char *s;if (dest <= src) {tmp = dest;s = src;while (count--)*tmp++ = *s++;} else {tmp = dest;tmp += count;s = src;s += count;while (count--)*--tmp = *--s;}return dest;}EXPORT_SYMBOL(memmove);#endif

【分析】

(1) memmove在复制是开辟了一个tmp和s的临时指针,而memcpy没有,这样做的优点在于不会改变src的数据,缺点是效率有所下降;

(2) 当dest指针的地址小于等于src的地址时,逐个复制时,dest++的地址总是小于等于src++的地址,不会因为地址重叠出现问题,因此采用类似于如下方式进行复制:

while (count--)*tmp++ = *s++;

(3) 当dest指针的地址大于src时,memcpy没有采取任何措施,保护src++的数据。

(4) 当dest指针的地址大于src时,memmove采用反序的方式进行复制,保证了从src取得数据的完整性,即在count范围内,src的数据不会因为src与dest地址重叠,而被覆盖。


原创粉丝点击