【问题标题】:Creating a Generic Circular Buffer创建通用循环缓冲区
【发布时间】:2012-11-29 02:44:55
【问题描述】:

鉴于希望从其内容中抽象出循环缓冲区的结构,并从以下代码段开始(由this wikipedia entry 提供):

typedef struct
{ 
    int value;
} ElemType;

typedef struct
{
    int         size;      /* total number of elements */
    int         start;     /* index of oldest element */
    int         count;     /* index at which to write new element  */
    ElemType   *elements;  /* vector of elements */
} CircularBuffer;

void cbInit(CircularBuffer *cb, int size) {
    cb->size  = size;
    cb->start = 0;
    cb->count = 0;
    cb->elements = (ElemType *)calloc(cb->size, sizeof(ElemType));
}

如何抽象元素类型,以便在定义 CircularBuffer 实例时指定它?到目前为止,我的尝试如下:

CircularBuffer *cbInit(uint16 size, void *element)
{
    CircularBuffer *buffer;

    buffer = malloc(sizeof(*buffer));

    if (buffer != NULL)
    {
        buffer->size = size;
        buffer->start = 0;
        buffer->count = 0;
        buffer->elements = (void *)calloc(size, sizeof(???));

        if (buffer->elements == NULL)
        {
            free(buffer);
            buffer = NULL;
        }
    }

    return buffer;
}

但我不知道如何确定未知类型的大小,它可能是 int、struct 或介于两者之间的任何类型。我正在尝试做的事情是否可能?

【问题讨论】:

  • 但是您将使用指向这些对象的指针,对吧?指针大小相同。 sizeof(void*)
  • 这是 C++ 模板让生活变得如此轻松的事情之一。在这里,您需要一个原始内存缓冲区并从用户那里传递大小。或者完全使用指针。
  • 有问题的代码用于缓冲嵌入式系统上的串行 UART 输入。我最初使用双向链表实现了缓冲区,但是考虑到每个节点的实际内容是单个字符,结构带来的开销太大了。我正在寻找一个中间地带,代码足够通用,可以重用,而在 RAM 使用方面没有太多开销。
  • 如果它用于 UART,你最好只使用 unsgined char(字节)的循环缓冲区。让它通用会花费你,你将永远铸造。另一种方法是为您想要的每种类型宏魔术生成循环缓冲区。

标签: c circular-buffer


【解决方案1】:

正如您所发现的,您无法自动判断未知数据的大小。您需要一个固定的元素类型(void* 是一个很好的通用选择),或者让用户传入每个元素的大小:

CircularBuffer *cbInit(uint16 size, int elementSize)
{
    ...
    buffer->elementSize = elementSize;
    buffer->elements    = calloc(size, elementSize);  
}

【讨论】:

  • 缓冲区将存储同质元素 - 也就是说,它们都将具有相同的大小。 sizeof(void*) 是指向 void 的指针的大小不是真的吗?如果是这样,鉴于它依赖于编译器并且与元素本身的大小无关,是什么使它成为一个好的通用选择?您是否建议我使用一个指针数组,每个指针指向一个元素?
  • @Zack 是的,或者是一个指针数组,每个指向一个元素;或者你可以存储任何东西,但用户必须明确地传递元素大小。这两个之一。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-05-25
  • 2018-10-29
  • 1970-01-01
  • 1970-01-01
  • 2019-06-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多