转载自:https://blog.csdn.net/caowei840701/article/details/8491836
关于memcpy和memmove两个c标准库函数,其功能都是将一块内存区域中的指定大小内容复制到目标内存中,在翻阅c标准库实现的源代码我们发现他们是有区别的。
首先看memcpy的实现:
-
void * __
cdecl memcpy (
-
void * dst,
-
const void * src,
-
size_t count
-
)
-
{
-
void * ret = dst;
-
-
#if defined (_M_MRX000) || defined (_M_ALPHA) || defined (_M_PPC)
-
{
-
extern void RtlMoveMemory( void *, const void , size_t count );
-
-
RtlMoveMemory( dst, src, count );
-
}
-
#else / defined (_M_MRX000) || defined (_M_ALPHA) || defined (_M_PPC) /
-
/
-
* copy from lower addresses to higher addresses
-
*/
-
while (count–) {
-
*(
char *)dst = *(
char *)src;
-
dst = (
char *)dst +
1;
-
src = (
char
)src + 1;
-
}
-
#endif / defined (_M_MRX000) || defined (_M_ALPHA) || defined (_M_PPC) */
-
-
return(ret);
-
}
-
再看memmove的实现:
-
void * __
cdecl memmove (
-
void * dst,
-
const void * src,
-
size_t count
-
)
-
{
-
void * ret = dst;
-
-
#if defined (_M_MRX000) || defined (_M_ALPHA) || defined (_M_PPC)
-
{
-
extern void RtlMoveMemory( void *, const void *, size_t count );
-
-
RtlMoveMemory( dst, src, count );
-
}
-
#else /* defined (_M_MRX000) || defined (_M_ALPHA) || defined (_M_PPC) */
-
if (dst <= src || (
char *)dst >= ((
char *)src + count)) {
-
/*
-
* Non-Overlapping Buffers
-
* copy from lower addresses to higher addresses
-
*/
-
while (count--) {
-
*(
char *)dst = *(
char *)src;
-
dst = (
char *)dst +
1;
-
src = (
char *)src +
1;
-
}
-
}
-
else {
-
/*
-
* Overlapping Buffers
-
* copy from higher addresses to lower addresses
-
*/
-
dst = (
char *)dst + count -
1;
-
src = (
char *)src + count -
1;
-
-
while (count--) {
-
*(
char *)dst = *(
char *)src;
-
dst = (
char *)dst -
1;
-
src = (
char *)src -
1;
-
}
-
}
-
#endif /* defined (_M_MRX000) || defined (_M_ALPHA) || defined (_M_PPC) */
-
-
return(ret);
-
}
仔细分析上面的代码不难看出,memcpy只是简单的将两块内存区域当作没有关系的相互独立内存区域进行内存的拷贝,而memmove则考虑了当两块内存区域有重叠时所采用不同方向的拷贝模式进行处理。
如上图所示,当源内存和目标内存出于第一种情况即两块内存区域相互独立时,memcpy和memmove都是可以正确处理的。在第二种情况下,两个函数都可以正常的实现内存拷贝。而当两块内存区域处于第三种情况时,很明显memcpy的实现存在问题,当将源内存块的开始字节拷贝到目标内存时,同时也会覆盖源内存块中的尚未拷贝的内存,导致从源内存在目标内存地址处开始的内存不能正确的拷贝。