简体   繁体   English

在结构中声明数组

[英]Declare array in struct

I am trying to make a struct for a circular buffer that contains an array of type "quote." 我正在尝试为包含类型为“ quote”的数组的循环缓冲区构造一个结构。 However, the quote array must start out at a size of 10. I am trying to figure out if I declare the size of 10 in my .h file or in my .c file. 但是,quote数组必须以10开头。我试图弄清楚是否在.h文件或.c文件中声明了10的大小。 My two files are as follows: 我的两个文件如下:

.h file: .h文件:

typedef struct{
    unsigned int time;
    double rate;

}quote;

typedef struct{

    unsigned int testNum;
    quote quoteBuffer[];

}cbuf;

cbuf* cbuf_init();

.c file: .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;


}

These are obviously just test values, however if I wanted to specifically make the quote array in the cbuf struct start out at a size of 10, would I declare that in the .h file as: 这些显然只是测试值,但是,如果我想专门使cbuf结构中的quote数组开始时的大小为10,我可以在.h文件中声明为:

typedef struct{

    unsigned int testNum;
    quote quoteBuffer[10];

}cbuf;

or in the .c file some other way? 或其他方式在.c文件中?

There are two ways of having dynamic arrays in structures. 在结构中具有动态数组有两种方法。 The obvious is of course to have it as a pointer, and dynamically allocate (or reallocate) when needed. 当然,显而易见的是,将其用作指针,并在需要时动态分配(或重新分配)。


The other is to have an array of size 1, and then allocate a larger size than the structure, to accommodate for the array: 另一种是具有大小为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;
}

Now you can use the array as a normal array: 现在,您可以将数组用作普通数组:

cbuf *buffer = cbuf_init();
buffer->quoteBuffer[5].time = 123;

Note: I only allocate extra space for 9 quote structures, but state that I allocate ten. 注意:我只为9个 quote结构分配额外的空间,但声明我分配了10个。 The reason is that the cbuf structure already contains one quote structure in its array. 原因是cbuf结构在其数组中已经包含一个quote结构。 1 + 9 = 10. :) 1 + 9 = 10::)

Note 2: I put the quote array in the cbuf structure with one entry already in it for backwards compatibility. 注2:我将quote数组放在cbuf结构中,其中已经有一个条目,以便向后兼容。 Having an array without a size in the structure is quite new in the C world. 在C语言世界中,结构中没有大小的数组是很新的。

you can also do this if you want 10 quotes in a cbuf but a statically allocated like quote buffer[10] would work too: 如果您希望在cbuf中使用10个引号,但也可以像引用缓冲区[10]这样静态分配,也可以这样做:

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

    return b;
}

If you want a statically sized circular buffer then your could declare the size in the header file. 如果要使用静态大小的循环缓冲区,则可以在头文件中声明大小。 Using a #define for the buffer size will make the code more readable and maintainable, as you'll reference the size elsewhere in your code. 使用#define作为缓冲区大小将使代码更具可读性和可维护性,因为您将在代码的其他地方引用该大小。

If you want the circular buffer to be growable then define the size in your C file. 如果希望循环缓冲区可增长,则在C文件中定义大小。 You'll then have to take care of tracking the size and destroying the memory that you will have to allocate dynamically. 然后,您将不得不跟踪大小并破坏必须动态分配的内存。

In your example, I think you need to allocate more room for your quote structs... 在您的示例中,我认为您需要为报价结构分配更多空间。

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

The reason for this is that in your struct def... 原因是在您的结构定义中...

quote quoteBuffer[];

... quoteBuffer doesn't add size to the struct. ... quoteBuffer不会增加结构的大小。 quoteBuffer will point to one byte past the end of the struct, hence the need to allocate memory for the struct + memory for the array. quoteBuffer将指向结构末尾的一个字节,因此需要为结构+数组分配内存。

EDIT: Daniel Fischer's comment (thanks Daniel) - quoteBuffer may, in some cases, add size to the struct if it introduces padding. 编辑:丹尼尔·菲舍尔(Daniel Fischer)的评论(感谢丹尼尔)-在某些情况下,如果quoteBuffer会引入填充,则可能会增加结构的大小。 The reason is that the compiler will probably strive to get the most optimal alignment for quoteBuffer. 原因是编译器可能会努力使quoteBuffer的最佳对齐方式。 For example, ints normally aligned of 4-byte boundaries. 例如,整数通常以4字节边界对齐。 Eg a struct like: 例如一个结构:

struct {
   char a;
   int b;
}

is probably changed by compiler to 被编译器更改为

struct {
   char a;
   char pad[3]; // compiler adds padding behind the scenes 
   int b; // align b on a 4-byte boundary
}

This probs doesn't apply in your case as your struct leaves quoteBuffer[] on a 4 byte boundary. 此问题不适用于您的情况,因为您的结构在4字节边界上保留了quoteBuffer []。

The reason that the compiler does this is two fold. 编译器执行此操作的原因有两个。 1. On some architectures (not so common nowadays I think?), unaligned accesses aren't supported. 1.在某些体系结构上(我认为现在不常见吗?),不支持未对齐的访问。 2. Aligned accesses are more efficient, even if architecture allows non-aligned accesses as it is one memory read as opposed to two memory reads plus a manipulation. 2.即使架构允许非对齐访问,对齐访问也会更高效,因为它是一次内存读取,而不是两次内存读取加上一个操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM