我回来了,似乎我还没有完全弄清楚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),它似乎突然写入我的容量值。
是什么给出了?
答案 0 :(得分:2)
您使用相同的名称buffer
进行两项不同的事情。一个用于循环缓冲区,另一个用于通过malloc
创建的存储。看看您在哪里设置buffer->head
和buffer->tail
。您将它们设置为结构本身,因此您将覆盖它。您需要将它们设置为通过malloc
创建的存储。