Bird
Raised Fist0
Embedded Cprogramming~20 mins

Ring buffer implementation in Embedded C - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Ring Buffer Mastery
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
Output of ring buffer enqueue and dequeue operations

Consider a ring buffer of size 4. After enqueuing 3 elements and dequeuing 1, what is the value returned by the next dequeue?

Embedded C
typedef struct {
    int buffer[4];
    int head;
    int tail;
    int max;
    int count;
} RingBuffer;

void enqueue(RingBuffer *rb, int val) {
    if (rb->count == rb->max) return; // full
    rb->buffer[rb->head] = val;
    rb->head = (rb->head + 1) % rb->max;
    rb->count++;
}

int dequeue(RingBuffer *rb) {
    if (rb->count == 0) return -1; // empty
    int val = rb->buffer[rb->tail];
    rb->tail = (rb->tail + 1) % rb->max;
    rb->count--;
    return val;
}

int main() {
    RingBuffer rb = {.head=0, .tail=0, .max=4, .count=0};
    enqueue(&rb, 10);
    enqueue(&rb, 20);
    enqueue(&rb, 30);
    dequeue(&rb);
    int result = dequeue(&rb);
    return result;
}
A20
B10
C30
D-1
Attempts:
2 left
💡 Hint

Remember that dequeue removes the oldest element first.

🧠 Conceptual
intermediate
1:30remaining
Ring buffer full condition check

Which condition correctly checks if a ring buffer is full?

Arb->count == rb->max
Brb->head == rb->tail
C(rb->head + 1) % rb->max == rb->tail
Drb->count == 0
Attempts:
2 left
💡 Hint

Count tracks how many elements are currently stored.

🔧 Debug
advanced
2:00remaining
Identify the bug in ring buffer enqueue function

What is the bug in this enqueue function for a ring buffer?

Embedded C
void enqueue(RingBuffer *rb, int val) {
    if (rb->count == rb->max) return;
    rb->buffer[rb->head] = val;
    rb->head = (rb->head + 1) % rb->max;
    rb->count++;
}
AThe buffer array is accessed out of bounds
BThe condition should be rb->count == rb->max, not >
CThe count should be decremented, not incremented
DThe head index should not wrap using modulo
Attempts:
2 left
💡 Hint

Check the condition that prevents adding when full.

📝 Syntax
advanced
1:30remaining
Syntax error in ring buffer initialization

Which option correctly initializes a ring buffer struct in C?

ARingBuffer rb = {head:0, tail:0, max:8, count:0};
BRingBuffer rb = [0, 0, 8, 0];
CRingBuffer rb = (head=0, tail=0, max:8, count=0);
DRingBuffer rb = {.head=0, .tail=0, .max=8, .count=0};
Attempts:
2 left
💡 Hint

Use designated initializers with dot notation in C.

🚀 Application
expert
2:30remaining
Calculate number of items after mixed operations

Given a ring buffer of max size 5, starting empty, after these operations:

  1. enqueue 1
  2. enqueue 2
  3. dequeue
  4. enqueue 3
  5. enqueue 4
  6. enqueue 5
  7. dequeue
  8. enqueue 6

How many items are currently stored in the buffer?

A3
B5
C4
D2
Attempts:
2 left
💡 Hint

Track count carefully after each enqueue and dequeue.

Practice

(1/5)
1.

What is the main purpose of the head pointer in a ring buffer?

easy
A. To reset the buffer to empty
B. To indicate where data will be read next
C. To store the total size of the buffer
D. To indicate where new data will be written next

Solution

  1. Step 1: Understand the role of head in ring buffer

    The head pointer marks the position where the next data element will be stored (written) in the buffer.
  2. Step 2: Differentiate head from tail

    The tail pointer is used for reading data, while the head is for writing new data.
  3. Final Answer:

    To indicate where new data will be written next -> Option D
  4. Quick Check:

    Head = write position [OK]
Hint: Head points to write location, tail points to read location [OK]
Common Mistakes:
  • Confusing head with tail pointer
  • Thinking head stores buffer size
  • Assuming head resets the buffer
2.

Which of the following is the correct way to advance the head pointer in a ring buffer of size BUFFER_SIZE after writing one element?

head = ?;
easy
A. head = BUFFER_SIZE - head;
B. head = head + 1;
C. head = (head + 1) % BUFFER_SIZE;
D. head = (head - 1) % BUFFER_SIZE;

Solution

  1. Step 1: Understand circular increment

    To move head forward in a circular buffer, increment and wrap around using modulo with buffer size.
  2. Step 2: Apply modulo operation

    The expression (head + 1) % BUFFER_SIZE ensures head wraps to 0 after reaching the end.
  3. Final Answer:

    head = (head + 1) % BUFFER_SIZE; -> Option C
  4. Quick Check:

    Use modulo to wrap index [OK]
Hint: Use modulo (%) to wrap pointer in ring buffer [OK]
Common Mistakes:
  • Not using modulo causes overflow
  • Subtracting instead of adding
  • Incorrect wrap calculation
3.

Given this code snippet for a ring buffer of size 4, what will be the value of head and tail after these operations?

int head = 0, tail = 0;
int BUFFER_SIZE = 4;

// Write 3 elements
for (int i = 0; i < 3; i++) {
    head = (head + 1) % BUFFER_SIZE;
}

// Read 1 element
tail = (tail + 1) % BUFFER_SIZE;
medium
A. head = 3, tail = 0
B. head = 3, tail = 1
C. head = 2, tail = 1
D. head = 1, tail = 1

Solution

  1. Step 1: Calculate head after writing 3 elements

    Starting at 0, head increments 3 times with modulo 4: head = (0+1)%4=1, then 2, then 3.
  2. Step 2: Calculate tail after reading 1 element

    Tail starts at 0, increments once: tail = (0+1)%4=1.
  3. Final Answer:

    head = 3, tail = 1 -> Option B
  4. Quick Check:

    Head=3, Tail=1 after ops [OK]
Hint: Increment pointers with modulo for each operation [OK]
Common Mistakes:
  • Forgetting modulo wrap
  • Mixing head and tail values
  • Counting increments incorrectly
4.

Identify the bug in this ring buffer write function and select the correct fix:

void write(int data) {
    if ((head + 1) == tail) {
        // Buffer full
        return;
    }
    buffer[head] = data;
    head = (head + 1) % BUFFER_SIZE;
}
medium
A. Change condition to ((head + 1) % BUFFER_SIZE) == tail
B. Remove the condition; buffer never gets full
C. Increment tail instead of head after write
D. Use head == tail to check full buffer

Solution

  1. Step 1: Analyze buffer full condition

    The buffer is full when the next head position wraps to tail, so modulo is needed to wrap index.
  2. Step 2: Correct condition with modulo

    Using ((head + 1) % BUFFER_SIZE) == tail correctly detects full buffer.
  3. Final Answer:

    Change condition to ((head + 1) % BUFFER_SIZE) == tail -> Option A
  4. Quick Check:

    Modulo needed for circular check [OK]
Hint: Always use modulo when comparing circular indices [OK]
Common Mistakes:
  • Missing modulo causes wrong full detection
  • Confusing head and tail roles
  • Incorrectly incrementing tail on write
5.

You want to implement a ring buffer that stores bytes and can hold exactly 8 bytes. Which of these buffer sizes and pointer update methods correctly avoids ambiguity between full and empty states?

Options:
  1. Buffer size = 8, full when (head + 1) % 8 == tail
  2. Buffer size = 9, full when (head + 1) % 9 == tail
  3. Buffer size = 8, full when head == tail
  4. Buffer size = 9, full when head == tail
hard
A. Use buffer size 9 with full condition (head + 1) % 9 == tail
B. Use buffer size 8 with full condition (head + 1) % 8 == tail
C. Use buffer size 8 with full condition head == tail
D. Use buffer size 9 with full condition head == tail

Solution

  1. Step 1: Understand full vs empty ambiguity

    When head == tail, buffer is empty. To distinguish full, buffer size is often set to capacity + 1.
  2. Step 2: Choose buffer size and condition

    Using buffer size 9 for 8 bytes capacity and full condition (head + 1) % 9 == tail avoids ambiguity.
  3. Final Answer:

    Use buffer size 9 with full condition (head + 1) % 9 == tail -> Option A
  4. Quick Check:

    Extra slot avoids full/empty confusion [OK]
Hint: Use buffer size one more than capacity to avoid confusion [OK]
Common Mistakes:
  • Using buffer size equal to capacity causes ambiguity
  • Checking full with head == tail
  • Not reserving one slot for full detection
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard