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

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

copy from the back

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

有帮助吗?

解决方案

从数学上讲,您不必担心它们是否根本重叠。如果 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从一开始就复制。

其他提示

memmove 如果两个内存区域不重叠,则可以变成一个纪念品。显然,Memcpy在大多数系统上都非常优化(我使用的系统之一是使用本书中的几乎所有技巧,从展开的循环到SSE操作,并获得了支持以获得最大的吞吐量)。

如果两个内存区域确实重叠,则出于所有意图和目的,要复制的区域都将移至临时缓冲区中,并将临时缓冲区复制(全部带有memcpy,很可能是Memcpy),回到原始缓冲区的顶部。您从一开始就无法工作,也不能从重叠的区域从后背工作,因为您总是会在此过程中至少损坏一些数据。

话虽如此,自从我查看LIBC代码以来已经很长时间了,因此我还没有考虑过对Memmove和重叠区域进行优化。

memmove并不取决于堆栈的生长方式 - 它仅将内存的一个区域复制到另一个位置 - 就像Memcpy一样,除了它处理重叠区域,而Memcpy没有。

编辑:实际上,考虑一下……如果您从正确的“源”(可以说),从背面工作可以工作,这取决于移动本身(例如,源是源<dest吗?)。您可以阅读Newlib的实现 这里, ,而且TT也得到了很好的评价。

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top