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

【更新说明】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地址重叠,而被覆盖。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值