内存重叠:拷贝的目的地址在源地址范围内。所谓内存重叠就是拷贝的目的地址和源地址有重叠。
在函数strcpy和函数memcpy都没有对内存重叠做处理的,使用这两个函数的时候只有程序员自己保证源地址和目标地址不重叠。
使用memmove函数可解决内存重叠问题。memmove函数对内存重叠做了处理。
重叠从两方面考虑:
(1).dest数据覆盖了source; 如:dest(8byte) 地址:1000
source(8byte) 地址:1002
(2).dest所指的区域本来就是source的一部分; 如:dest(8byte) 地址:1000
source(8byte) 地址:0998
例如:针对第一种交叉情况情况,dst<src且dst+count>src,memcpy和memmove的结果是一样的。请看下面的例子讲解:
string s = "hello world";
memmove(&s[0],&s[5],10);
1.下面来看strcpy(): 字符串拷贝.
char *strcpy(char *strDest, const char *strSrc)
{
assert((strDest!=NULL) && (strSrc !=NULL));
char *address = strDest;
while( (*strDest++ = * strSrc++) != '\0')
;
return address ;
}2.下面来看下memcpy函数:内存拷贝
void *memcpy(void *dest, const void *source, size_t count)
{
assert((NULL != dest) && (NULL != source));
char *tmp_dest = (char *)dest;
char *tmp_source = (char *)source;
while(count --)//不对是否存在重叠区域进行判断
*tmp_dest ++ = *tmp_source ++;
return dest;
}3.下面来看下memmove函数:
void* _memmove(void* dest, const void* src, size_t count)
{
assert(src != nullptr && dest != nullptr);
char* tmp_dest = (char*)dest;
const char* tmp_src = (const char*)src;
if (tmp_src < tmp_dest)//当src地址小于dest地址时,从后向前拷贝,保证dest数据正确
{
tmp_src += count - 1;
tmp_dest += count - 1;
while (count--)
*tmp_dest-- = *tmp_src--;
}
else if (tmp_src > tmp_dest)//当src地址大于dest地址时,从前向后拷贝,保证dest数据正确
{
while (count--)
*tmp_dest++ = *tmp_src++;
}
//else(tmp_src==tmp_dest) 此时不进行任何操作
return dest;
}以上是我自己的理解,下面是百度的别人的代码,有待研究:
void *memmove(void *dest, const void *source, size_t count)
{
assert((NULL != dest) && (NULL != source));
char *tmp_source, *tmp_dest;
tmp_source = (char *)source;
tmp_dest = (char *)dest;
if((dest + count<source) || (source + count) <dest))
{// 如果没有重叠区域
while(count--)
*tmp_dest++ = *tmp_source++;
}
else
{ //如果有重叠(反向拷贝)
tmp_source += count - 1;
tmp_dest += count - 1;
while(count--)
*--tmp_dest = *--tmp;
}
return dest;
}...
本文详细解释了内存拷贝中常见的strcpy、memcpy与memmove函数的区别,重点在于如何处理内存重叠的问题,通过代码示例说明了不同情况下这些函数的行为。
405

被折叠的 条评论
为什么被折叠?



