是否可以将不同类型的结构存储到一个灵活长度的数组中?

时间:2012-11-22 10:07:20

标签: c

假设我们有两种结构类型,如下所示:

struct A {
    int a;
}

struct B {
    int b;
    int c;
}

是否可以使用指定的初始值设定项初始化一个灵活长度数组以包含 A和B的实例,例如:

<sometype> my_array[] = {
    ((struct A){ .a = 10, }),
    ((struct B){ .b = 1, .c = 5, }),
};

因为我需要知道数组中元素的类型,所以在结构之前放置一些char的方法也会很好。 :)

我知道这看起来非常糟糕,但我试图将一些类似字节码的数据结构打包在一起,这看起来像是一种优雅的方式来定义它们(好吧,至少在某些宏的帮助下)。

修改:澄清几点:

  • 动态分配不是一个选项
  • 也不是工会 - 我希望元素能够完全占用其类型所需的空间
  • 问题中的“可变长度数组”可能会产生误导 - 根据http://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html,确切的面额将是“灵活长度数组”。理想情况下,示例代码是我希望它的样子。

所以我基本上喜欢的是能够将一些任意的结构化数据打包到一个在二进制文件的.data段中分配的内存区域。我不需要随机访问元素,只需要从结构中打包数据 - 在我的例子中使用灵活的长度数组是因为这个结构似乎是我想要实现的最接近的。但声明可能是其他任何工作(除了汇编程序,我需要保留C可移植性)。

1 个答案:

答案 0 :(得分:5)

最好的方法是使用工会。您可以在union中定义所有类型,包括此联盟和char,您希望将 的实际类型定义为struct。< / p>

struct TypesAB {
    char type;
    union {
        struct {
            int a;
        } A;
        struct {
            int b;
            int c;
        } B;
    };
};
enum {
    TypeA,
    TypeB
};

使用此struct,您可以定义数组,然后设置元素。

struct TypesAB array[10];
array[0].type = TypeA;
array[0].A.a = 10;
array[1].type = TypeB;
array[1].B.b = 1;
array[1].B.c = 5;

请注意,如果AB类型的长度不同,则内存布局会使您占用一些空间。实际上,根据上面的定义,struct TypesAB将被定义为sizeof大到足以容纳A或B中的较大者以及char。如果您将其用作A,则用于c成员的内存空间丢失。相同的内存空间用于a的{​​{1}}成员和A的{​​{1}}成员。