求大牛围观求回答memmove 函数内存覆
发布时间: 2013-07-08 14:13:00 作者: rapoo
求大牛围观,求回答memmove 函数内存覆盖的条件,谢谢!!
我在一个博客看到的一个代码,不明白memmove 函数中内存覆盖的条件,向大牛请教下!
代码:
void * __cdecl memmove ( void * dst,const void * src,size_t count)
{
void * ret = dst;
if (dst <= src || (char *)dst >= ((char *)src + count))
{
// 若dst和src区域没有重叠,则从起始处开始逐一拷贝
while (count--)
{
*(char *)dst = *(char *)src;
dst = (char *)dst + 1;
src = (char *)src + 1;
}
}
else
{ // 若dst和src 区域交叉,则从尾部开始向起始位置拷贝,这样可以避免数据冲突
dst = (char *)dst + count - 1;
src = (char *)src + count - 1;
while (count--)
{
*(char *)dst = *(char *)src;
dst = (char *)dst - 1;
src = (char *)src - 1;
}
}
return(ret);
}
我的疑问:
(1)内存重叠应该分两种情况,如下图所示,判断对应的不内存重叠的条件不应该仅仅是
(dst <= src || (char *)dst >= ((char *)src + count) 吧?

(2)由于待拷贝区域src指向的字符串是const 类型的,也就是说是不能改变的,但是在内存重叠时,可能会改变源地址的内容啊?
(3)既然从后往前拷贝可以完成该函数的功能,那直接使用从尾部往开始处拷贝不是更方便吗?为什么还要执行从开始处往尾部拷贝呢?
求大牛解释!!
[解决办法]1. 应该是注释错误, 这种情况不是没有区域有重叠. 而是从前往后拷贝, 覆盖的地方只会是已经读过的内容. 还没有读取的内容不会被覆盖掉的. 所以可以保证正常.
2. const 只是对 C++ 起提示和语法检查作用. 是起不到对内存的保护作用的.
3. 对有些情况, 从后面拷贝就不行了呀. 比如 dst < src, dst + count > src 的时候, 从后面开始拷贝, 第一个字符拷贝过去就会覆盖到 src 前面的字符. 而前面的字符还没读取过, 就有问题了!
[解决办法]你图中2的情况,从尾部开始拷贝就错误了
图中1的情况,虽然有重叠,但是从头部开始拷贝不会出问题,所以没有加进判断条件
[解决办法]四种情况:
1:无重叠,两种方法都可以,选择正向复制。
2:dest尾部与src首部重叠,选择正向复制,以免冲掉src中未复制的数据。
3:dest首部与src尾部重叠,选择反向复制,以免冲掉src中未复制的数据。
4:完全重叠,两种方法都可以,选择正向复制(其实最好不复制)
[解决办法]对的呀, 你要保证源内容不变, 参数内存又有重叠, 本来就是不可能完成的任务, memcpy 返回失败表示不可能完成正是它该做的.