mem中的C实现

bre*_*ett 6 c memmove

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

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

copy from the back
Run Code Online (Sandbox Code Playgroud)

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

pax*_*blo 30

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

如果src并且dst相等,请立即退出.

那是因为您的案例是以下之一:

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----->
Run Code Online (Sandbox Code Playgroud)

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

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

  • 好吧,无论你是一次复制一个字节,还是四字或一些大规模的SSE9 1024位超字值,理论都是一样的.您必须确保不复制_into_尚未复制_out of_的重叠区域.在它不是N值的直接倍数的情况下,引入的所有N-is-wide-to-char选项都是更复杂的重叠检测(和最终转移). (2认同)

Mat*_*lin 6

如果两个内存区域不重叠,则memmove可以转换为memcpy.很明显,memcpy在大多数系统上都经过了极大的优化(我使用的其中一个系统几乎使用了本书中的每一个技巧,从展开的循环到支持最大吞吐量的SSE操作).

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

如此说来,它一直以来我看过的libc代码很长一段时间,所以有可能是,我没有考虑过的的memmove和重叠区域的优化.

的memmove不依赖于堆栈增长在所有的方式 - 它只是将内存的一个区域到另一个位置 - 酷似的memcpy,只是它处理重叠的区域和memcpy没有.

编辑:其实,想着它多一些......从后面的工作,如果你从右边的"源"可以去上班(这么说),这取决于移动本身(例如,为源<目的地或不?).您可以阅读newlib的实现在这里,和TT的相当良好注释了.