C memmove相当于for loop - segfault
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C memmove相当于for loop - segfault相关的知识,希望对你有一定的参考价值。
我正在使用动态调整大小来实现环形缓冲区。当尾部在头部后面时,缓冲区末尾的数据必须在调整大小后移动到缓冲区的新端。为了做到这一点,我做了以下代码:
memmove(self->broadcaster.events+self->broadcaster.events_head+self->broadcaster.events_size,
self->broadcaster.events+self->broadcaster.events_head,
self->broadcaster.events_size-self->broadcaster.events_head);
其中self->broadcaster.events_size
是旧的大小(new_size / 2)。不幸的是,它会导致分段错误。我认为这个代码是等价的:
for (i = 0 ; i < self->broadcaster.events_size - self->broadcaster.events_head ; ++i)
self->broadcaster.events[self->broadcaster.events_size+self->broadcaster.events_head+i]=
self->broadcaster.events[self->broadcaster.events_head+i];
但这种天真的for循环实现正常工作,所以我似乎不知道如何正确使用memmove
。这两段代码有何不同?
答案
如果sizeof(*self->broadcaster.events) == 1
,他们只相当。
为清楚起见,我用self->broadcaster
用b
和events
替换了e
,并为你的代码添加了一些空格。
memmove(b.e + b.e_head + b.e_size, b.e + b.e_head, b.e_size - b.e_head);
将只复制b.e_size - b.e_head
字节和循环:
for (i = 0 ; i < b.e_size - b.e_head ; ++i)
b.e[b.e_size + b.e_head + i] = b.e[b.e_head + i];
将复制(b.e_size - b.e_head) * sizeof *b.e
字节,因为每个b.e[...] = b.e[...]
赋值通过sizeof *b.e
字节移动,并且每个++i
正在通过b.e[... + i]
字节推进sizeof *b.e
的地址。
如果您定义宏,您将获得最佳服务:
#define MOVE(dst, src, count) memmove((dst), (src), (count) * sizeof *(src))
并使用它而不是memmove
。
但你当然可以将memmove
的最后一个参数改为
(self->broadcaster.events_size-self->broadcaster.events_head)*sizeof*self->broadcaster.events
以上是关于C memmove相当于for loop - segfault的主要内容,如果未能解决你的问题,请参考以下文章