c - 环形缓冲区困难

标签 c linux data-structures queue circular-buffer

我已经尝试在 C 中实现环形缓冲区/循环队列。

它应该通过 argv 获取所有参数,将它们一个一个地插入队列,然后以相同的方式将它们从队列中弹出,并在输出时打印它们。

代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <errno.h>

struct buffer
{
    int32_t front, rear, capacity, *array;
};

__attribute__ ((noreturn)) void prog_error(const char* str)
{
    perror(str);
    exit(1);
}

struct buffer *init_queue(int32_t size)
{
    struct buffer *queue = malloc(sizeof(struct buffer));

    if (!queue)
        return NULL;

    queue->capacity = size;
    queue->front = -1;
    queue->rear = -1;
    queue->array = malloc(queue->capacity * sizeof(int32_t));

    if (!queue->array)
        return NULL;

    return queue;
}


void enqueue(struct buffer *queue, int32_t x)
{
    if (((queue->rear + 1) % queue->capacity == queue->rear))
        prog_error("Queue overflow");

    queue->rear = (queue->rear + 1) % queue->capacity;
    queue->array[queue->rear] = x;

    if (queue->front == -1)
        queue->front = queue->rear;
}

int32_t dequeue(struct buffer *queue)
{
    int32_t data = 0;

    if (queue->front == -1)
        prog_error("Queue underflow");

    data = queue->array[queue->front];

    if (queue->front == queue->rear)
        queue->front = queue->rear = -1;

    queue->front = (queue->front + 1) % queue->capacity;

    return data;
}

int main(int argc, char **argv)
{
    if (argc < 2)
        prog_error("Too few arguments");

    int32_t size = (int32_t) argc - 1;

    struct buffer *queue;

    if (!(queue = init_queue(size)))
        prog_error("Allocation error");

    for (int32_t i = 1; i < size; ++i)
        enqueue(queue, (int32_t) atoi(argv[i]));

    for (int32_t i = 0; i < size; ++i)
        printf("%" PRId32 "\n", dequeue(queue));

    free(queue);
}

但是最后一个值总是被 1 代替。

而且,如果我正好给它 1 个值,那么它会下溢(或者这是环形缓冲区的正常行为?)。 我该如何解决这个问题?

最佳答案

循环

for (int32_t i = 1; i < size; ++i)

如果 argc = 2 则不循环

然后,如果您将单个 arg 传递给您的应用程序,则不会在您的队列中插入任何数据,并且

if (queue->front == -1)

由于 init_queuedequeue 函数始终为 true

同样的事情传递了更多的参数。由于 i=1 的起始值,您总是会跳过参数。

关于c - 环形缓冲区困难,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35199060/

相关文章:

linux - 比较字符与 Intel x86_64 汇编

c - 向数组末尾插入 n 个元素的时间复杂度是多少?

C goto循环不起作用

Java进程占用越来越多的内存

Java:将数组的数组转换为集合的集合,反之亦然

algorithm - 在完美二叉树中获取顶点的父节点

php - 用于大型数组的 php in_array 替代方案,用于避免重复条目

c - 了解如何编写缓存友好的代码

使用 pthread.h 进行多线程 C 编程

c - UART 没有读取我想要的那么多数据