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

时间:2015-11-07 19:02:46

标签: c memory undefined-behavior circular-buffer

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

我决定稍微简化它,而不是为我想为整数构建一个数据类型构建缓冲区。在大多数情况下,我能够遵循逻辑,虽然我不明白作者是如何偶尔将值转换为(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++;
}

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

是什么给出了?

1 个答案:

答案 0 :(得分:2)

您使用相同的名称buffer进行两项不同的事情。一个用于循环缓冲区,另一个用于通过malloc创建的存储。看看您在哪里设置buffer->headbuffer->tail。您将它们设置为结构本身,因此您将覆盖它。您需要将它们设置为通过malloc创建的存储。