C 中的 memmove 实现

发布于 2024-09-16 05:22:09 字数 165 浏览 9 评论 0原文

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

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

copy from the back

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

Can some one help me to understand how memmove is implemented in C. I have only one special condition right ?

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

copy from the back

Also does it depend on the way stack grows ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

时光与爱终年不遇 2024-09-23 05:22:09

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

Mathematically, you don't have to worry about whether they overlap at all. If src is less than dst, just copy from the end. If src is greater than dst, just copy from the beginning.

If src and dst are equal, just exit straight away.

That's because your cases are one of:

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----->

Even if there's no overlap, that will still work fine, and simplify your conditions.

If you have a more efficient way to copy forwards than backwards then, yes, you should check for overlap to ensure you're using the more efficient method if possible. In other words, change option 1 above to copy from the beginning.

听不够的曲调 2024-09-23 05:22:09

如果两个内存区域不支持,memmove 可以变成 memcpy重叠。显然,memcpy 在大多数系统上都经过了极其优化(我使用的系统之一几乎利用了书中的所有技巧,从展开循环到支持最大吞吐量的 SSE 操作)。

如果两个内存区域确实重叠,则出于所有意图和目的,要复制的区域将被移动到临时缓冲区中,并且临时缓冲区将被复制(很可能全部使用 memcpy)回到原始缓冲区的顶部。您不能从头开始工作,也不能从后面开始处理重叠区域,因为在这个过程中您总是会遇到至少一些数据被损坏的情况。

话虽这么说,我已经很久没有查看 libc 代码了,所以可能有一个我还没有想到的针对 memmove 和重叠区域的优化。

memmove 根本不依赖于堆栈增长的方式 - 它只是将内存的一个区域复制到另一个位置 - 与 memcpy 完全相同,只是它处理重叠区域,而 memcpy 不处理。

编辑:实际上,再考虑一下...如果您从正确的“源”(可以这么说)开始,从后面开始工作就可以工作,具体取决于移动本身(例如,源是否<目标?) 。您可以在此处阅读newlib的实现,而且它的评论也相当不错。

memmove can be turned into a memcpy if the two memory regions don't overlap. Obviously memcpy is extremely optimised on most systems (one of the ones I use makes use of almost every trick in the book from unrolled loops to SSE operations where supported for maximum throughput).

If the two memory regions do overlap, for all intents and purposes the region to be copied is moved into a temporary buffer and the temporary buffer is copied (all with memcpy, most likely) back on top of the original buffer. You can't work from the start or work from the back with an overlapping region, because you'll always end up with at least some data being corrupted in the process.

That being said, it's been a long time since I've looked at libc code, so there may be an optimisation for memmove and overlapping regions that I haven't thought of yet.

memmove doesn't depend on the way the stack grows at all - it merely copies one region of memory to another location - exactly like memcpy, except that it handles overlapping regions and memcpy doesn't.

EDIT: Actually, thinking about it some more... Working from the back can work if you go from the right "source" (so to speak), depending on the move itself (eg, is source < dest or not?). You can read newlib's implementation here, and tt's fairly well-commented too.

番薯 2024-09-23 05:22:09

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

Depends on the compiler. Good compilers will use good optimizations dependent on the target processor instruction set and bus width.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文