在 C 中实现循环缓冲区,得到未定义的行为

Implementing Circular Buffer in C, getting undefined behavior

我回来了,看来我还没有完全弄清楚 C 中的内存管理。在尝试设计事件队列时,我决定构建一个循环缓冲区作为练习。经过一些研究后,我尝试在我在 SO 上看到的以下实现之后对其进行建模: .

我决定稍微简化一下,而不是为任何数据类型构建一个缓冲区,我只想为整数构建一个缓冲区。在大多数情况下,我能够遵循逻辑,尽管我不明白作者为什么偶尔会将值转换为 (char *)。我已经尝试过使用和不使用 (char *) 强制转换的程序,但在这两种情况下它都会产生相同的错误输出。

一旦我写入超过某个点,缓冲区中不应更改的值就会受到影响,我认为这与我为缓冲区分配内存的方式有关。看起来程序正在写入我在我的结构中分配的缓冲区,并且正在覆盖本来应该是静态的值。我这辈子都想不出如何解决这个错误,但我暗暗怀疑这是我设法忽略的非常明显的事情。

这是我的代码:

typedef struct Circular_buffer
{
    void *buffer;
    void *buffer_end;
    size_t capacity; // The maximum number of items allowed in buffer
    size_t count; // Current number of items in buffer
    size_t item_size; //Size of each item;
    void *head;
    void *tail;
}  Circular_buffer;

int main(void)
{
    int i;
    Circular_buffer my_buffer; 
    c_buff_init( &my_buffer, 10 );
    printf("Buffer Capacity: %d\n", my_buffer.capacity);
    for (i = 0; i < 7; i++) {
        c_buff_write( &my_buffer, i);
    }
    printf("Capacity: %d Count: %d\n", my_buffer.capacity, (int)my_buffer.count);
    cleanup_c_buff( my_buffer );
    return 0;
}


void *c_buff_init( Circular_buffer *buffer, int length )
{
     buffer->item_size = sizeof(int);
     buffer->buffer = malloc( length * buffer->item_size );
     buffer->buffer_end = buffer->buffer + buffer->capacity * buffer->item_size;
     buffer->capacity = length;
     buffer->count = 0;
     buffer->head = buffer;
     buffer->tail = buffer;
}

void c_buff_write( Circular_buffer *buffer, const int data)
{
    if (buffer->count == buffer->capacity) {
        printf( "Your buffer is full\n" );
        exit(0);
        }
    printf("Buffer Capacity: %d Buffer Count %d\n", buffer->capacity, buffer->count);
    memcpy( buffer->head, &data, buffer->item_size); // memcpy args = (dest, src, size)
    buffer->head = (char*)buffer->head + buffer->item_size; 
    if (buffer->head == buffer->buffer_end) // If head has reached end of buffer
        buffer->head = buffer->buffer;      // Set head to start of buffer
    buffer->count++;
}

当这个程序运行时,它会产生预期的输出,直到它尝试添加第五个元素(呵呵),它似乎突然覆盖了我的容量值。

什么给了?

您使用相同的名称 buffer 来表示两个不同的事物。一个用于循环缓冲区,另一个用于您通过 malloc 创建的存储。查看您设置 buffer->headbuffer->tail 的位置。您将它们设置为结构本身,因此您将覆盖它。您需要将它们设置为您通过 malloc.

创建的存储