通用环形缓冲区扩容后数据异常问题求助
Let's break down why your ring buffer is showing corrupted data after pushing 15 elements—the core issues are in your RingResize function, plus a minor test code quirk that's adding confusion.
Key Bugs in RingResize
1. Incorrect Memory Size Calculation
Your realloc call is calculating the new buffer size completely wrong. buffer->dataLen tracks the number of elements, not bytes, so you need to multiply the new element count by the size of each element to get the total bytes needed.
Original (broken) code:
newMemory = realloc(buffer->data, buffer->dataLen + (buffer->resizeBy * buffer->dataSize))
For your test case (10 ints, resize by 2), this only allocates 10 + (2*4) = 18 bytes—but you actually need (10+2)*4 = 48 bytes for 12 ints. This causes memory overflow, leading to corrupted data and garbage values.
2. (Secondary) Data Positioning Logic (Made Irrelevant by the First Bug)
While your head position adjustment (buffer->head = buffer->elemCount) is correct for a full buffer, it doesn't matter if you don't allocate enough memory first. Once the size is fixed, this logic works fine to align the head at the end of existing data for new pushes.
Fixed RingResize Function
Replace your current RingResize with this corrected version:
unsigned char RingResize(RingBuffer* buffer) { int newDataLen = buffer->dataLen + buffer->resizeBy; // Calculate total bytes for the new buffer (cast to size_t to avoid overflow) size_t newTotalSize = (size_t)newDataLen * buffer->dataSize; unsigned char* newMemory = NULL; if ((newMemory = realloc(buffer->data, newTotalSize)) == NULL) { return 1; // Allocation failed } buffer->data = newMemory; buffer->dataLen = newDataLen; // When buffer was full, head matches tail—move head to end of existing data buffer->head = buffer->elemCount; return 0; }
Fix for Confusing Test Output
In your Test.c push loop, this line accesses out-of-bounds memory once the buffer expands:
printf(" %d", ((int*)(Ring.data))[i]);
i runs from 0 to 14, but your buffer only grows to 16 elements after two resizes. When i exceeds the current dataLen, you're reading unallocated/garbage memory. Instead, print the element you just pushed by targeting the actual head position (adjusted for the post-Push increment):
// Inside the push loop, replace the problematic printf with this: int lastWritePos = (Ring.head - 1 + Ring.dataLen) % Ring.dataLen; printf(" %d", ((int*)(Ring.data))[lastWritePos]);
What Happens After Fixing?
- The buffer will correctly expand to 12, then 14, then 16 elements as you push 15 integers.
- No memory overflow means no corrupted data—your final buffer will contain all 1-15 values correctly.
- The read loop will retrieve all values in order without garbage.
内容的提问来源于stack exchange,提问作者Korsarq

