0

What is the right way to write this code? I want to make a circular buffer that will receive as a parameter a pointer to some type of data. This way I wrote not working. I have problem with circular_buf_put function. It says invalid use of void expression. error: invalid use of void expression cb->data[cb->head]=data; What is right way to use it here?

typedef struct circular_buf{
    void *data;
    size_t tail;
    size_t head;
    size_t capacity;
    size_t objectSize; 
    size_t size; 
} circular_buf;

int circular_buf_init(struct circular_buf *cb, void *data, size_t objectSize, size_t capacity)
  {
  cb->data=data;
  cb->objectSize=objectSize;
  cb->capacity=capacity;
  cb->tail=0;
  cb->head=0;
  cb->size=0;
   }

void circular_buf_put(circular_buf *cbuf, void  *data)
{
    cbuf->data[cbuf->head] = data;
    cbuf->head++;
    cbuf->size++;

}
9
  • IMHO, the right way to implement a circular buffer is with an array. When using array, you can access elements by index. This allows you to use the % operator to wrap-around. Commented Sep 26, 2021 at 18:17
  • You aren't updating the head at all, so you'll always overwrite the same slot. Commented Sep 26, 2021 at 18:17
  • You haven't provided a definition for cbuf_handle_t (or whatever circular_buf_t that I would assume it's a pointer to). Please provide enough information to be able to see the problem, and some details about what is specificially giving you that error. Commented Sep 26, 2021 at 18:28
  • For a start, read the descriptions of the tags you applied and then delete the wrong one! As a new user, also take the tour and read How to Ask. Commented Sep 26, 2021 at 18:29
  • 1
    @gag Describe the role of member .objectSize. Commented Sep 26, 2021 at 21:20

2 Answers 2

1

it say invalid use of void expression.

Because of this line:

cbuf->data[cbuf->head] = data;

You are dereferencing a void pointer, which is illegal in C. You need to cast it to another type before you can dereference it.

Sign up to request clarification or add additional context in comments.

5 Comments

Is there way to use it here but to dereferene in main?
@gag What do you mean exactly?
I want to make a universal buffer that will receive any type of data, and in the main I will determine which type it will be. My idea was to use a void pointer as the type of data that buffer will recieve but I'm not sure how to do it here.
@gag You can use unsigned char *data instead of void *data to be able to dereference it. See 0___________'s answer.
@gag C has no universal type for any pointer. void * can enclode any object pointer, but may be too small for function pointers.
1

I would implement it this way. You do not need so much information in the structure. You only need to know the tail, head, size in elements and the element size.

typedef struct
{
    size_t tail;
    size_t head;
    size_t size; 
    size_t obj_size;
    unsigned char data[];
} circular_buf;

circular_buf *create(size_t size, size_t obj_size)
{
    circular_buf *cb = malloc(sizeof(*cb) + size * obj_size);
    if(cb)
    {
        cb -> tail = 0;
        cb -> head = 0;
        cb -> size = size;
        cb -> obj_size = obj_size;
    }
    return cb;
}

size_t inc(size_t val, circular_buf *cb)
{
    if(val == cb -> size - 1) val = 0;
    else val++;

    return val;
}

int circular_buf_put(circular_buf *cb, const void *data)
{
    size_t new_tail = inc(cb -> tail, cb);
    if (new_tail == cb -> head) return -1; // buffer full
    memcpy(&cb->data[cb -> tail * cb -> size], data, cb -> obj_size);
    cb -> tail = new_tail;
    return 0;
}

1 Comment

Nice use of malloc(sizeof(*cb) + size * obj_size).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.