有人可以帮助我理解如何在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以从头开始复制.
如果两个内存区域不重叠,则memmove可以转换为memcpy.很明显,memcpy在大多数系统上都经过了极大的优化(我使用的其中一个系统几乎使用了本书中的每一个技巧,从展开的循环到支持最大吞吐量的SSE操作).
如果两个内存区域确实重叠,则为了所有意图和目的,将要复制的区域移动到临时缓冲区中,并将临时缓冲区(最有可能是memcpy)复制回原始缓冲区之上.您无法从一开始就工作,也不能从后面开始使用重叠区域,因为在此过程中至少会有一些数据被破坏.
如此说来,它一直以来我看过的libc代码很长一段时间,所以有可能是,我没有考虑过的的memmove和重叠区域的优化.
的memmove不依赖于堆栈增长在所有的方式 - 它只是将内存的一个区域到另一个位置 - 酷似的memcpy,只是它处理重叠的区域和memcpy没有.
编辑:其实,想着它多一些......从后面的工作,如果你从右边的"源"可以去上班(这么说),这取决于移动本身(例如,为源<目的地或不?).您可以阅读newlib的实现在这里,和TT的相当良好注释了.