HiveBrain v1.2.0
Get Started
← Back to all entries
patterncMinor

Circular Buffer

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
circularbufferstackoverflow

Problem

For my current project I need a circular buffer, which is able to do the following things:

  • Push something to it (to the head).



  • Pop something from it (from the tail). I don't need the popped data.



  • Peak the head and tail (no popping).



  • Iterate through the currently contained elements.



Here is my C implementation.

circularBuffer.h:

#ifndef CIRCULAR_BUFFER_H
#define CIRCULAR_BUFFER_H

#include 
#include 

struct circularBuffer {
  void *data;         // Holds the buffer data.
  size_t headOffset;  // The next position the buffer will write to.
  size_t tailOffset;  // The position of the buffer tail.
  size_t elementSize; // Size of one element contained in the buffer.
  size_t numElements; // Number of elements the buffer is able to hold at once.
  bool   isEmpty;     // Flag, which holds, whether the buffer is empty. 
                      // Allows to fill the whole buffer without losing the ability 
                      // to determine, whether its empty or not.
};

struct circularBuffer *circularBuffer_create(size_t numElements, size_t elementSize);

// Push/Pop
void  circularBuffer_push(struct circularBuffer *buf, void *ptr);
int   circularBuffer_popTail(struct circularBuffer *buf);

// Get data
size_t circularBuffer_containedCount(struct circularBuffer *buf);
void *circularBuffer_peakTail(struct circularBuffer *buf);
void *circularBuffer_peakHead(struct circularBuffer *buf);

#endif /* !defined CIRCULAR_BUFFER_H */


circularBuffer.c:

```
#include
#include

#include "circularBuffer.h"

struct circularBuffer *circularBuffer_create(size_t numElements, size_t elementSize) {
struct circularBuffer *tmp = calloc(1, sizeof(struct circularBuffer));

if (!tmp) { return NULL; }

tmp->data = malloc(numElements * elementSize);

if (!tmp->data) {
free(tmp);
return NULL;
}

tmp->numElements = numElements;
tmp->elementSize = elementSize;
tmp->isEmpty = true;

return tmp;
}

void circularBuffer_push(struct circularBuffer *buf, v

Solution

-
void * data;

results in the

warning: arithmetic on a pointer to void is a GNU extension [-Wpointer-arith]
  memcpy(buf->data + buf->headOffset*buf->elementSize, ptr, buf->elementSize);


For portability make it char * data;.

-
Fail early

If a condition

buf->data + buf->headOffset != 0


ever fails, the structure is badly corrupted. You should fail immediately, with as much noise as possible (the core dump suffices). In no case you can mask the problem.

Code Snippets

warning: arithmetic on a pointer to void is a GNU extension [-Wpointer-arith]
  memcpy(buf->data + buf->headOffset*buf->elementSize, ptr, buf->elementSize);
buf->data + buf->headOffset != 0

Context

StackExchange Code Review Q#123155, answer score: 4

Revisions (0)

No revisions yet.