随机访问联合体数组的成员

时间:2018-08-29 07:53:05

标签: c unions

简化示例:

typedef union {
    int foo;
    char* bar;
} int_or_str;

void baz() {
    int_or_str* bogus = malloc(sizeof(int_or_str) * 43);
    bogus[42].bar = "test";
    printf("%s\n", bogus[42].bar);
}
  1. 如果这样做,编译器会假设bogus的所有42个成员都是char指针吗? (显然,我可以尝试一下,但要强调“应该”。)
  2. 它甚至定义了当您以这种方式访问​​一个联合数组时会发生什么情况吗?
  3. 假设我想要一个实际上包含大小不同的值的联合数组,这合法吗? (如果我确定联合成员在内存中的布局方式,我可以单独存储布局并计算偏移量。)

如果您想知道这个问题的动机:基本上,我正在尝试为运行时定义的结构提供解决方案。我的想法是要有一个联合数组来表示结构字段,外加一些记录如何访问这些字段的元数据。

1 个答案:

答案 0 :(得分:2)

广告1:是的,它会起作用。

广告2:是的,它的定义很完美。

广告3:是的,这是合法的。

union的整体思想是它可以容纳不同类型的元素。联合的大小将是联合中最大元素的大小。在64位系统上,大小可能为char *

因此,不,编译器将不会假定所有元素都是char指针。这就是为什么必须使用点符号在语句中告诉编译器要访问哪种类型的元素,然后编译器将生成访问权限。

但是正如汤姆所说,您不知道当前存储的是哪种类型的元素;您必须知道某个外部原因(信息)。如果知道这一点很重要,则应将信息存储在数据结构中,例如:

typedef struct {
    int whatisthis;
    union {
        int foo;
        char *bar;
    } u;
} int_or_str;

并将其设置为:

int_or_str example;
example.whatisthis= 1;
example.u.foo= 1;

example.whatisthis= 2;
example.u.bar= "test";

并按如下方式访问:

if (example.whatisthis==1) printf("%d\n", example.u.foo);
if (example.whatisthis==2) printf("%s\n", example.u.bar);