代码之家  ›  专栏  ›  技术社区  ›  wvxvw

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

  •  2
  • wvxvw  · 技术社区  · 7 年前

    简化示例:

    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 是字符指针吗?(显然,我可以试试这个,但强调“应该”)。
    2. 它是否定义了以这种方式访问联合数组时会发生什么?
    3. 假设,我想要一个实际持有不同大小值的联合数组,这是合法的吗?(如果我确定联合成员在内存中的布局方式,我可以单独存储布局,并计算偏移量)。

    1 回复  |  直到 7 年前
        1
  •  2
  •   Paul Ogilvie    7 年前

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

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

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

    所以不,编译器不会假设所有元素都是字符指针。这就是为什么你必须在语句中使用dot notation告诉编译你想访问哪种类型的元素,编译器将生成访问。

    但正如Tom所说,您不可能知道当前存储的元素类型;必须有一个外部原因(信息)让您知道这一点。如果了解它很重要,则应将信息存储在数据结构中,例如:

    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);