循环缓冲区在第 6 个元素之后没有给出正确的缓冲区大小

Posted

技术标签:

【中文标题】循环缓冲区在第 6 个元素之后没有给出正确的缓冲区大小【英文标题】:Circular buffer does not give the correct size of the buffer after 6-th element 【发布时间】:2021-03-19 15:04:27 【问题描述】:

我已经用 C 语言编写了循环缓冲区的代码,它在某种程度上运行良好。我将缓冲区的大小设为 10。当我将缓冲区填充到元素 6 时 - 它工作正常。但是在我填充第 7 个元素的那一刻 - 我得到结果“缓冲区的大小等于 767”。对于元素 8 - 它不起作用。我使用“head”来编写和“tail”来提取值。你能帮我解决这个问题吗?

#include<stdio.h>
#include<stdint.h>
#include <stdbool.h>


typedef struct RingBuffer 
   uint16_t* buffer;
   size_t head;
   size_t tail;
   size_t max;
   bool full;

*cbuf_handle_t;

cbuf_handle_t init_RingBuffer (uint8_t* buffer, size_t size)

   cbuf_handle_t cbuf = malloc (sizeof(cbuf_handle_t));
   cbuf->buffer = buffer;
   cbuf->max = size;
   return cbuf;




void RingBuffer_free(cbuf_handle_t cbuf)

   free(cbuf);


void RingBuffer_reset(cbuf_handle_t cbuf)
   cbuf->head = 0;
   cbuf->tail = 0;
   cbuf->full = false;
   

bool RingBuffer_full (cbuf_handle_t cbuf)

   return cbuf->full;


bool RingBuffer_empty(cbuf_handle_t cbuf)

       return (!cbuf->full && (cbuf->tail == cbuf->head));


size_t RingBuffer_Capacity(cbuf_handle_t cbuf)
   return cbuf->max;


size_t RingBuffer_size(cbuf_handle_t cbuf)
   size_t size = cbuf->max;

   if (!cbuf->full)
   if (cbuf->head >= cbuf->tail)
       
       size = (cbuf->head - cbuf->tail);
       else
       
       size = (cbuf->head - cbuf->tail + cbuf->max);
       
       
        return size;
   



void RingBuffer_AdvancePointer(cbuf_handle_t cbuf)
   if (cbuf->full)
       cbuf->tail = (cbuf->tail+1)%cbuf->max;
   

   cbuf->head = (cbuf->head + 1)%cbuf->max;
   cbuf->full = (cbuf->head == cbuf->tail);


void RingBuffer_retreatPointer (cbuf_handle_t cbuf)
   cbuf->full = false;
   cbuf->tail = (cbuf->tail + 1)%cbuf->max;


void RingBuffer_addValue (cbuf_handle_t cbuf, uint8_t data)
   cbuf->buffer[cbuf->head] = data;
   RingBuffer_AdvancePointer(cbuf);


   

int RingBuffer_Remove (cbuf_handle_t cbuf, uint8_t *data)
   int r = -1;
   if (!RingBuffer_empty(cbuf))
       *data = cbuf->buffer[cbuf->tail];
       RingBuffer_retreatPointer(cbuf);
       r = 0;
   
   return r;




int main ()



uint8_t arr[10];
cbuf_handle_t cpt = init_RingBuffer(arr, 10);

//initialzie the buffer, tail and head and max

int i = 0;
RingBuffer_reset(cpt);


for ( i = 0 ; i< 6; i++)
   RingBuffer_addValue(cpt, i);



size_t size = RingBuffer_size(cpt);
printf("The size of the buffer %d", size);



提前谢谢你!

问候

罗斯季斯拉夫

【问题讨论】:

想想malloc (sizeof(cbuf_handle_t)) 真正分配了多少内存......这是将指针隐藏在类型别名后面如此危险的原因之一。 您将要查看:Is it a good idea to typedef pointers?。 【参考方案1】:

如cmets中所说,一般不建议将结构声明为指针。但是,您可以通过使用 malloc 更改分配方式来修复该错误:

cbuf_handle_t cbuf = malloc (sizeof(*cbuf));

这是因为,cbuf 是一个指向结构的指针,如果您取消引用它,当您将其传递给 sizeof 时,您将获得结构以及它的实际大小。

【讨论】:

以上是关于循环缓冲区在第 6 个元素之后没有给出正确的缓冲区大小的主要内容,如果未能解决你的问题,请参考以下文章

为什么PKWARE网站上的ZIP APPNOTE没有在其规范中提到正确的密码检查机制?

圆形缓冲区(循环buffer)实现

PAT1067-----正则表达式的进一步了解,程序对输入的程序的操作(键盘缓冲区)

Java频率分析性能

VBO 没有在 LWJGL 中正确创建

OpenGL索引缓冲区对象元素顺序绘制不正确