我想构建一个环形缓冲区API,但是与其在API本身中使用malloc()动态创建缓冲区,不如传递已经存在的变量类型数组(uint8_t、uint16_t等)。
因此,我认为实现这一目标的最佳方法是声明一个包含所有所需信息和所需API函数的结构。
typedef struct ring_buffer {
void * buffer;
uint8_t element_size;
size_t head;
size_t tail;
size_t max;
bool full;
} ring_buffer_t;
ring_buffer_t buf_init(void * buffer, uint8_t element_size, size_t max);
void buf_add(ring_buffer_t * handle, uint8_t element);
bool buf_is_emtpy(ring_buffer_t * handle);
void* buf_pop(ring_buffer_t * handle);
ring_buffer_t buf_init(void * buffer, uint8_t element_size, size_t max){
return (ring_buffer_t){.buffer = buffer, .element_size = 2, .head=0, .tail=0, .max=64, .full=false};
}
void buf_add(ring_buffer_t * handle, const uint8_t element){
if(handle->head == handle->max){
handle->head = 0;
}
printf("adding %d at position %d\n", element, (uint8_t)handle->head);
handle->buffer[handle->head] = element;
handle->head += handle->element_size;
}
void* buf_pop(ring_buffer_t * handle){
void* ret;
if(handle->tail < handle->head-1){
printf("Tail is at position %d\n", (uint8_t)handle->tail);
ret = &handle->buffer[handle->tail];
handle->tail += handle->element_size;
} else {
printf("Tail is at position %d\n", (uint8_t)handle->tail);
ret = &handle->buffer[handle->tail];
}
return ret;
}
bool buf_is_emtpy(ring_buffer_t * handle){
if(handle->head == handle->tail){
return true;
} else {
return false;
}
}但这并不是无效的*似乎不是正确的事情来处理这个问题。我如何处理指针,我知道在我创建结构时的大小?因为在buf_add()中,为了添加element,我需要将handle->buffer转换成正确的指针类型。
怎样才是解决这一问题的正确办法?
根据给出的答案,我改变了行文
handle->buffer[handle->head] = element;
至
memcpy(&handle->buffer[handle->head], element, handle->element_size);
到目前为止,什么是有效的,但仍然给我一个警告,我是dereferencing 'void *' pointer --当然是这样,但是在这种情况下,正确的取消引用会是什么样子呢?
发布于 2019-07-31 06:54:32
看看memcpy()和朋友们。由于不能提供类型时不能使用简单的赋值,所以需要复制非类型化的存储块。
请尽可能提高编译命令的警告级别。你提供的消息来源有一些怪癖。;-)
编辑1
怪人发现:
GCC 8.1.0 (MinGW 64位)添加后用-Wall -Wextra报告的警告
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>buf_init有未使用的参数,element_size和max。源使用常量。
还有关于取消引用void*指针和分配要添加的元素的警告。当然,因为消息来源是不正确的。
我也会使用size_t作为element_size的类型,因为它代表一个大小。
GCC和-pedantic一起对指针算法提出警告。但我们是故意的。
编辑2
有关取消引用void*指针的警告是正确的,因此请替换
&handle->buffer[offset]通过这个
handle->buffer + offset您必须实现“手工”的地址计算。
如果使用索引而不是偏移量,则必须按元素的大小添加乘法:
handle->buffer + index * handle->element_size另一个问题:memcpy()需要一个指针作为第二个参数..。这是我的建议:
void buf_add(ring_buffer_t * handle, void *element) {
if (handle->head == handle->max) {
handle->head = 0;
}
memcpy(handle->buffer + handle->head, element, handle->element_size);
handle->head += handle->element_size;
}https://stackoverflow.com/questions/57284668
复制相似问题