首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >圆形RingBuffer

圆形RingBuffer
EN

Code Review用户
提问于 2012-10-12 13:13:02
回答 3查看 21K关注 0票数 13

我正在尝试进入C程序,我认为尝试实现循环缓冲区是个好主意。

我像这样定义了我的结构:

代码语言:javascript
复制
typedef struct
{
     int8_t* buffer;
     int8_t* buffer_end;
     int8_t* data_start;
     int8_t* data_end;
     int64_t count;
     int64_t size;
 } ring_buffer;

和职能:

代码语言:javascript
复制
void RB_init(ring_buffer* rb, int64_t size)
{
    rb->buffer = malloc(sizeof(int8_t) * size);
    rb->buffer_end = rb->buffer + size;
    rb->size = size;
    rb->data_start = rb->buffer;
    rb->data_end = rb->buffer;
    rb->count = 0;
}

void RB_free(ring_buffer* rb)
{
    free(rb->buffer);
}

bool RB_push(ring_buffer* rb, int8_t data)
{
    if (rb == NULL || rb->buffer == NULL)
        return false;

    *rb->data_end = data;
    rb->data_end++;
    if (rb->data_end == rb->buffer_end)
        rb->data_end = rb->buffer;

    if (RB_full(rb)) {
        if ((rb->data_start + 1) == rb->buffer_end)
            rb->data_start = rb->buffer;
        else
            rb->data_start++;
    } else {
        rb->count++;
    }

    return true;
}

int8_t RB_pop(ring_buffer* rb)
{
    if (rb == NULL || rb->buffer == NULL)
        return false;

    int8_t data = *rb->data_start;
    rb->data_start++;
    if (rb->data_start == rb->buffer_end)
        rb->data_start = rb->buffer;
    rb->count--;

    return data;
}

bool RB_full(ring_buffer* rb)
{
    return rb->count == rb->size;
}

我做了一些测试,看起来效果很好。你能提出一些改进建议吗?

EN

回答 3

Code Review用户

回答已采纳

发布于 2013-01-14 18:29:36

这个看起来不错。它的可读性很强,而且可能很快。

有时,环形缓冲区包装是通过使用以下类型的剩余部分和偏移来实现的:

代码语言:javascript
复制
end_offset = (end_offset + 1) % size;

但我喜欢你的做法,没有补偿和分裂。

一些小发现:

  1. NULL指针在RB_pop中检查可以防止分段错误,但调用方将获得返回值为零。因此调用方不会知道零是错误还是成功的结果。int8_t RB_pop(ring_buffer* rb) {如果(rb == NULL \ rb->buffer == NULL)返回false;
  2. RB_popRB_push都进行检查:rb == NULL。也许其他功能也应该这样做。
票数 7
EN

Code Review用户

发布于 2014-04-12 00:01:21

我同意@User1 1关于RB_pop()的观点,并想在其中添加以下内容:

为了防止函数返回false的意外返回值,您应该使函数void并有第二个参数data。如果第一个条件语句是return,这也允许您尽早使用false

代码语言:javascript
复制
void RB_pop(ring_buffer* rb, int8_t* data)
{
    if (rb == NULL || rb->buffer == NULL)
        return;

    // update data parameter...
}
票数 7
EN

Code Review用户

发布于 2018-11-28 11:53:52

你没有在pop函数中检出count。如果缓冲区为空,您将返回垃圾,同时计数也将为负数。

票数 0
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/16468

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档