我正在尝试为包含“quote”类型的数组的循环缓冲区创建一个结构。但是,引用数组必须以10的大小开始。我试图找出是否在我的.h文件或我的.c文件中声明大小为10。我的两个文件如下:
.h文件:
typedef struct{
unsigned int time;
double rate;
}quote;
typedef struct{
unsigned int testNum;
quote quoteBuffer[];
}cbuf;
cbuf* cbuf_init();
.c文件:
cbuf* cbuf_init(){
cbuf *buffer = (cbuf *)calloc(1,sizeof(cbuf));
buffer->testNum = 1;
quote newQuote = {1,1.00};
buffer->quoteBuffer[1] = newQuote;
return buffer;
}
这些显然只是测试值,但是如果我想在cbuf结构中专门使引用数组的大小为10,我会在.h文件中声明为:
typedef struct{
unsigned int testNum;
quote quoteBuffer[10];
}cbuf;
或.c文件中的其他方式?
答案 0 :(得分:2)
有两种方法可以在结构中使用动态数组。显而易见的当然是将它作为指针,并在需要时动态分配(或重新分配)。
另一种是使用大小为1的数组,然后分配比结构更大的大小,以适应数组:
typedef struct {
unsigned int testNum;
quote quoteBuffer[1];
} cbuf;
cbuf *cbuf_init(const size_t num_quotes) {
/* Allocate for the `cbuf` structure, plus a number of `quote`
* structures in the array
*/
cbuf *buffer = malloc(sizeof(cbuf) + (num_quotes - 1) * sizeof(quote));
/* Other initialization */
return buffer;
}
/* If more quotes are needed after initial allocation, use this function */
cbuf *cbuf_realloc(cbuf *buffer, const size_t new_num_quotes) {
buffer = realloc(buffer, sizeof(cbuf) + (new_num_quotes - 1) * sizeof(quote));
/* Other initialization */
return buffer;
}
现在您可以将数组用作普通数组:
cbuf *buffer = cbuf_init();
buffer->quoteBuffer[5].time = 123;
注意:我只为 9 quote
结构分配额外空间,但声明我分配了十个。原因是cbuf
结构在其数组中已经包含一个quote
结构。 1 + 9 = 10. :))
注2:我将quote
数组放在cbuf
结构中,其中已有一个条目,以便向后兼容。在C世界中,在结构中没有大小的数组是一个全新的。
答案 1 :(得分:1)
如果你想在一个cbuf中使用10个引号,你也可以这样做但是静态分配的类似报价缓冲区[10]也可以这样做:
cbuf* cbuf_init(int numQuotes)
{
cbuf *b = calloc(1, sizeof(cbuf) + numQuotes * sizeof(quote));
return b;
}
答案 2 :(得分:1)
如果你想要一个静态大小的循环缓冲区,那么你可以在头文件中声明大小。使用#define作为缓冲区大小将使代码更具可读性和可维护性,因为您将在代码中的其他位置引用该大小。
如果希望循环缓冲区可增长,则在C文件中定义大小。然后,您必须注意跟踪大小并破坏您必须动态分配的内存。
在您的示例中,我认为您需要为报价结构分配更多空间......
cbuf *buffer = (cbuf *)calloc(1,sizeof(cbuf) + NUM_QUOTES*sizeof(struct quote));
---------------------------------
原因在于你的struct def ...
quote quoteBuffer[];
... quoteBuffer不会为结构添加大小。 quoteBuffer将指向结构末尾的一个字节,因此需要为数组的struct +内存分配内存。
编辑:Daniel Fischer的评论(感谢Daniel) - 在某些情况下,如果引入填充,quoteBuffer可能会为结构添加大小。原因是编译器可能会努力为quoteBuffer获得最佳的对齐方式。例如,通常对齐4字节边界的int。例如。结构如:
struct {
char a;
int b;
}
可能由编译器改为
struct {
char a;
char pad[3]; // compiler adds padding behind the scenes
int b; // align b on a 4-byte boundary
}
这个probs不适用于你的情况,因为你的struct在4字节边界上留下了quoteBuffer []。
编译器执行此操作的原因有两个。 1.在某些架构上(我认为现在不常见?),不支持未对齐的访问。 2.对齐访问更有效,即使架构允许非对齐访问,因为它是一个内存读取而不是两个内存读取加上操作。