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

在C中实现循环缓冲区,获得未定义的行为,c,memory,undefined-behavior,circular-buffer,C,Memory,Undefined Behavior,Circular Buffer,我回来了,似乎我还没有完全理解C语言中的内存管理。在尝试设计事件队列时,我决定构建一个循环缓冲区作为练习。经过一点研究,我正试图根据我在这里看到的以下实现对其进行建模: 我决定将它简化一点,而不是为任何数据类型构建缓冲区,我只想为整数构建一个缓冲区。在大多数情况下,我能够遵循逻辑,尽管我不明白作者为什么偶尔会将值转换为(char*)。我已经尝试过我的程序有(char*)类型转换和没有(char*)类型转换,但在这两种情况下都会产生相同的错误输出 一旦写入超过某个点,缓冲区中不应更改的值就会受到影

我回来了,似乎我还没有完全理解C语言中的内存管理。在尝试设计事件队列时,我决定构建一个循环缓冲区作为练习。经过一点研究,我正试图根据我在这里看到的以下实现对其进行建模:

我决定将它简化一点,而不是为任何数据类型构建缓冲区,我只想为整数构建一个缓冲区。在大多数情况下,我能够遵循逻辑,尽管我不明白作者为什么偶尔会将值转换为(char*)。我已经尝试过我的程序有(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++;
}
typedef结构循环\u缓冲区
{
空*缓冲区;
无效*缓冲区结束;
size\u t capacity;//缓冲区中允许的最大项目数
size\u t count;//缓冲区中的当前项目数
size\u t item\u size;//每个项目的大小;
空*头;
空*尾;
}环形缓冲区;
内部主(空)
{
int i;
循环缓冲区我的缓冲区;
c_buff_init(&my_buffer,10);
printf(“缓冲区容量:%d\n”,我的缓冲区容量);
对于(i=0;i<7;i++){
c_buff_write(&my_buffer,i);
}
printf(“容量:%d计数:%d\n”,my\u buffer.Capacity,(int)my\u buffer.Count);
清理缓冲区(我的缓冲区);
返回0;
}
void*c_buff_init(循环缓冲区*buffer,整数长度)
{
缓冲区->项目大小=sizeof(int);
缓冲区->缓冲区=malloc(长度*缓冲区->项目大小);
buffer->buffer\u end=buffer->buffer+buffer->capacity*buffer->item\u size;
缓冲->容量=长度;
缓冲区->计数=0;
缓冲器->头部=缓冲器;
缓冲器->尾部=缓冲器;
}
无效c_buff_写入(循环缓冲区*缓冲区,常量int数据)
{
如果(缓冲区->计数==缓冲区->容量){
printf(“您的缓冲区已满\n”);
出口(0);
}
printf(“缓冲区容量:%d缓冲区计数%d\n”,缓冲区->容量,缓冲区->计数);
memcpy(buffer->head,&data,buffer->item_size);//memcpy args=(dest,src,size)
缓冲区->头=(字符*)缓冲区->头+缓冲区->项目大小;
if(buffer->head==buffer->buffer\u end)//如果head已到达缓冲区的末尾
buffer->head=buffer->buffer;//将head设置为缓冲区的开头
缓冲->计数++;
}
当这个程序运行时,它会产生预期的输出,直到它尝试添加第五个元素(heh),它似乎突然写入了我的容量值


给了什么?

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

创建的存储。请使用调试器。天哪,我知道我应该更具创造性地使用我的名字。太谢谢你了,我很尴尬这件事太琐碎了。