Hello everybody,
I need to implement a circular buffer and im clue less . . .HELP me:'(

Dani AI

Generated

— drawing it out like suggested is useful. Below is a compact, practical C reference you can drop into a project. It uses head/tail indices plus a full flag so "empty vs full" is unambiguous. rb_put fails when full; rb_put_force overwrites the oldest entry if you prefer that behaviour.

#include <stdlib.h>
#include <stdint.h>

struct ring_buffer {
    uint8_t *buf;
    size_t head;
    size_t tail;
    size_t max; /* capacity */
    int full;   /* 0 or 1 */
};

int rb_init(struct ring_buffer *rb, size_t size)
{
    rb->buf = malloc(size);
    if (!rb->buf) return -1;
    rb->max = size;
    rb->head = rb->tail = 0;
    rb->full = 0;
    return 0;
}

void rb_free(struct ring_buffer *rb) { free(rb->buf); rb->buf = NULL; }

int rb_empty(const struct ring_buffer *rb) { return (!rb->full && rb->head == rb->tail); }
int rb_full(const struct ring_buffer *rb) { return rb->full; }

size_t rb_size(const struct ring_buffer *rb)
{
    if (rb->full) return rb->max;
    if (rb->head >= rb->tail) return rb->head - rb->tail;
    return rb->max + rb->head - rb->tail;
}

int rb_put(struct ring_buffer *rb, uint8_t data)
{
    if (rb->full) return -1;
    rb->buf[rb->head] = data;
    rb->head = (rb->head + 1) % rb->max;
    rb->full = (rb->head == rb->tail);
    return 0;
}

int rb_put_force(struct ring_buffer *rb, uint8_t data)
{
    rb->buf[rb->head] = data;
    if (rb->full) rb->tail = (rb->tail + 1) % rb->max; /* drop oldest */
    rb->head = (rb->head + 1) % rb->max;
    rb->full = (rb->head == rb->tail);
    return 0;
}

int rb_get(struct ring_buffer *rb, uint8_t *data)
{
    if (rb_empty(rb)) return -1;
    *data = rb->buf[rb->tail];
    rb->full = 0;
    rb->tail = (rb->tail + 1) % rb->max;
    return 0;
}

Key notes: all ops are O(1). Common bugs are off-by-one errors, forgetting to allocate max>0, and not clearing full after a read. For multi-threaded producer/consumer use, add locks or make the single-producer/single-consumer case lock-free with atomic loads/stores. If you need speed, pick a power-of-two capacity and replace % max with a bitmask. To test, use a tiny buffer (like size 4) and exercise wrap-around, full, empty, and overwrite paths.

Recommended Answers

All 3 Replies

THanks a bunch . . btw ive read the article and the problem is implementation . . actually i dont have a strong programing background and i need a C reference implementation . . but still thanks alot

Try drawing it out on paper first to help you visualize what you're trying to do. Believe me, it helps. For a more hands-on approach, you can try reading an article like this:
http://www.vias.org/cppcourse/chap20_05.html

It gives it in C++, but it does a decent job at explaining how the buffers work with the two pointers (well, in this case, I'd guess you'll be implementing them as indices).

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.