I've tried implementing a ring buffer/cyclical queue in C.
It is supposed to take all of the arguments via argv, push them onto the queue one by one, and then pop them off of the queue in the same fashion, printing them on the way out.
Here is the code:
#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); } But the last value is always replaced by a 1.
And also, if I give it exactly 1 value then it underflows (or is that normal behavior for a ring buffer?). How can I fix this?