c - C memmove 相当于 for 循环 - segfault
问题描述
我正在实现具有动态调整大小的环形缓冲区。当 tail 在 head 之后时,缓冲区末尾的数据必须在调整大小后移动到缓冲区的新末尾。为此,我编写了以下代码:
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
.
但是您当然可以将 to 的最后一个参数更改memmove
为
(self->broadcaster.events_size-self->broadcaster.events_head)*sizeof*self->broadcaster.events
推荐阅读
- javascript - For循环不会在每次迭代时停止
- django - 如何在 django 中制作更新功能
- python - 熊猫(系列和数据帧)中布尔索引的较短方法?
- python-3.x - 计算器按钮不起作用并给出“未定义”错误消息
- docker - 在 Docker 中设置 GOOGLE_APPLICATION_CREDENTIALS
- linux - 如何正确使用此 cp 命令
- mysql - Nodejs mysql时区问题
- javascript - javascript箭头函数传递了未定义的参数,这是如何工作的?
- python - 用于查找未转义字符的 Python 正则表达式
- office-js - Office 加载项 (Office.js) 的设置 API 在 Excel 中不起作用