0

我正在尝试为包含“引用”类型的数组的循环缓冲区创建一个结构。但是,报价数组必须以 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 文件中?

4

3 回答 3

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,但声明我分配了 10 个。原因是该cbuf结构的数组中已经包含一个quote结构。1 + 9 = 10。:)

注意 2:为了向后兼容,我将quote数组放入cbuf结构中,其中已有一个条目。在结构中拥有一个没有大小的数组在 C 世界中是相当新的。

于 2013-04-29T08:40:43.040 回答
1

如果你想在一个 cbuf 中有 10 个引号,你也可以这样做,但是像引用缓冲区 [10] 这样的静态分配也可以:

cbuf* cbuf_init(int numQuotes)
{
    cbuf *b = calloc(1, sizeof(cbuf) + numQuotes * sizeof(quote));

    return b;
}
于 2013-04-29T08:40:15.513 回答
1

如果您想要一个静态大小的循环缓冲区,那么您可以在头文件中声明大小。使用#define 作为缓冲区大小将使代码更具可读性和可维护性,因为您将在代码的其他地方引用大小。

如果您希望循环缓冲区可增长,请在 C 文件中定义大小。然后,您必须注意跟踪大小并销毁您必须动态分配的内存。

在您的示例中,我认为您需要为报价结构分配更多空间...

cbuf *buffer = (cbuf *)calloc(1,sizeof(cbuf) + NUM_QUOTES*sizeof(struct quote));
                                             ---------------------------------

原因是在你的 struct def...

quote quoteBuffer[];

... quoteBuffer 不会增加结构的大小。quoteBuffer 将指向结构末尾之后的一个字节,因此需要为结构分配内存 + 为数组分配内存。

编辑:Daniel Fischer 的评论(感谢 Daniel)——quoteBuffer 在某些情况下,如果它引入了填充,它可能会增加结构的大小。原因是编译器可能会努力为 quoteBuffer 获得最佳对齐。例如,整数通常与 4 字节边界对齐。例如像这样的结构:

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
}

此问题不适用于您的情况,因为您的结构将 quoteBuffer[] 保留在 4 字节边界上。

编译器这样做的原因有两个。1. 在某些架构上(我认为现在不常见?),不支持未对齐的访问。2. 对齐访问更有效,即使架构允许非对齐访问,因为它是一次内存读取,而不是两次内存读取加上一次操作。

于 2013-04-29T08:46:00.457 回答