C memmove 相当于 for 循环 - 段错误

标签 c segmentation-fault buffer memmove

我正在实现具有动态调整大小的环形缓冲区。当 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->broadcasterbeventse并在代码中添加了一些空格。

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 循环 - 段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52349766/

相关文章:

rust - 如何更新 Bytes/BytesMut 的一部分?

python - Python 的 C 和 C++ 库如何跨平台?

c++ - CMake 编译时定义

C 如何书写放大的数字

c++ - 大数组上的段错误

google-cloud-functions - 将 Base64 图像字符串传递给调用 Cloud Vision API 的 Firebase 可调用云函数

c - C 中的递归函数(2 个子数组)

c - 解码这些 Valgrind 调试器内存错误在我的代码中意味着什么

c - C get 行中的段错误

c++ - 为什么会出现缓冲区溢出?我怎样才能避免它? [C++]