mem中的C实现

时间:2010-08-26 05:41:42

标签: c memmove

有人可以帮助我理解如何在C中实现memmove。我只有一个特殊条件吗?

if((src<dst)&&((src+sz) > dst))

copy from the back

它还取决于堆栈的增长方式吗?

3 个答案:

答案 0 :(得分:29)

在数学上,你不必担心它们是否重叠。如果src小于dst,请从最后复制。如果src大于dst,则只需从头开始复制。

如果srcdst相等,请立即退出。

那是因为你的案件是以下之一:

1) <-----s----->                start at end of s
                 <-----d----->

2) <-----s----->                start at end of s
            <-----d----->

3) <-----s----->                no action
   <-----d----->

4)          <-----s----->       start at beginning of s
   <-----d----->

5)               <-----s----->  start at beginning of s
   <-----d----->

即使没有重叠,这仍然可以正常工作,并简化您的条件。

如果您有一种更有效的方式来复制前进而不是后退,那么,是的,您应该检查重叠以确保您使用更有效的方法(如果可能)。换句话说,更改上面的选项1以从头开始复制。

答案 1 :(得分:5)

如果两个内存区域不重叠,则可以将

memmove转换为memcpy。 memcpy显然在大多数系统上都得到了极大的优化(我使用的其中一个系统使用了本书中几乎所有技巧,从展开的循环到支持最大吞吐量的SSE操作)。

如果两个内存区域重叠,则为了所有意图和目的,将要复制的区域移动到临时缓冲区中,并将临时缓冲区(最有可能是memcpy)复制回原始缓冲区之上。你不能从一开始就工作,或者从后面开始工作,重叠区域,因为你总是会在这个过程中至少有一些数据被破坏。

话虽如此,自从我查看libc代码已经有很长一段时间了,因此可能会对memmove和重叠区域进行优化,而我还没有想到。

memmove根本不依赖于堆栈的增长方式 - 它只是将一个内存区域复制到另一个位置 - 就像memcpy一样,除了它处理重叠区域而memcpy没有。

编辑:实际上,再考虑一下......如果你从正确的“来源”(可以这么说)出发,可以从后面工作,这取决于移动本身(例如,来源&lt; dest或不?)。你可以阅读newlib的实现here,而且评论也相当好。

答案 2 :(得分:1)

取决于编译器。好的编译器将根据目标处理器指令集和总线宽度使用良好的优化。