struct Register
数组,每个寄存器的动态分配数组为struct Field
?Register_A.FieldArray[23].High
吗?)?如何有效地初始化寄存器结构(假设寄存器结构数组很大)? (就像没有花费任何计算的数据段一样)
struct Field
{
char High;
char Low;
char Attribute;
};
struct Register
{
unsigned int ResetValue;
struct Field FieldArray[];
};
答案 0 :(得分:3)
我强烈反对你不使用弹性阵列,因为它们只不过是一块硬币。您应该声明并将其用作struct Field *
,malloc
将其设置为与任何其他动态数组一样大小。
那就是malloc
,数组大小为n_elem
:
struct Register register = malloc(sizeof(*register) + n_elem * sizeof(*register->FieldArray));
访问元素:
char high = register->FieldArray[0].High;
对于初始化:in gcc, at least,,您可以像任何其他静态数组一样静态初始化数组部分。我不确定其他编译器如何处理它。
为什么不鼓励使用flex数组:
我会链接this post,但我不认为答案是完整的(大多数沮丧是因为它只是c-99),所以我会添加我的想法。
他们是个例外。从本质上讲,您声明数组的大小为零,并且每次都在界限范围内访问它,只是在您分配的范围内。您不能像任何其他结构一样使用具有灵活数组的结构,例如你不能把sizeof
灵活的数组拿走。如果声明一个静态的或一个数组,则不能使用该数组成员,因为没有为它分配空间。
在数组中使用它们的示例:
#include <stdio.h>
struct test {
int val;
int arr[];
};
int main() {
struct test tarr[2];
printf("%p\n%p\n", &tarr[0].arr[0], &tarr[1].val);
}
输出:
0x7fff59b67164
0x7fff59b67164
他们在同一个地址。如果尝试写入数组成员,则会覆盖下一个对象。如果您尝试从中读取,则从下一个对象读取数据。根据填充,这甚至可能是填充的无意义值。
它们就像goto
语句一样,两者都有用,但往往是个坏主意。如果您不知道为什么它们是危险的,您就不应该使用它们(在实际代码中;在测试程序中使用它们以了解如何正确使用它们以及它们如何引入它们并不是一个坏主意问题)。
答案 1 :(得分:1)
一种方法是改变struct Register
:
struct Register
{
unsigned int ResetValue;
struct Field FieldArray[1];
};
struct Register *Register_Create()
{
struct Register *reg = calloc(1, sizeof(struct Register) - sizeof(struct Field));
// check for NULL pointer
return reg;
}
struct Register *Register_SetSize(struct Register *reg, size_t size)
{
// check for NULL
reg = realloc(reg, sizeof(struct Register) + sizeof(struct Field) * (size - 1));
// check for NULL
return reg;
}
以下是如何使用它的示例:
struct Register *reg = Register_Create();
reg = Register_SetSize(register, 5);
// You now have space for 5 elements in reg->FieldArray
reg->FieldArray[3].High = 'B';
请注意,只有在FieldArray
末尾放置struct
时,此解决方案才有效。
答案 2 :(得分:0)
你必须知道FieldArray有多大。如果未修复,则需要声明最大值。然后您可以按照指定的方式分配注册和访问
答案 3 :(得分:0)
灵活阵列成员是C99的一部分。
struc
灵活数组成员:malloc(sizeof(struct Register) + sizeof(struct Field[n]))
,其中n
是您想要的大小。不要忘记初始化数组并跟踪n
,最好通过将成员专门用于此目的顺便说一句:上面的malloc
可能由于填充而浪费了一些字节,但通常不值得考虑确切的公式。最小的一个有最大值并使用offsetof
。