为联合分配内存以及联合指针和指针联合之间的区别

时间:2018-03-13 15:17:52

标签: c pointers casting unions

由于我的问题here无法自信地回答,我再次在这里问,希望有人确切知道:

  1. 指向union的指针和包含指向其元素的指针的union之间是否有任何区别(除了语法之外)? this示例中生成的程序集完全相同。
  2. 只要我从不访问其他成员,是否允许仅为其中一个成员(不是最大的成员)分配内存?
  3. 关于第二个问题,C89草案的6.5.2.1说:

      

    union的大小足以包含其最大的成员 - 最多一个成员的值可以随时存储在union对象中。指向union对象的指针适当地转换为指向其每个成员的指针(或者如果成员是位字段,则指向它所在的单位),反之亦然。

    所以,至少在正确转换时,只为其中一个成员分配空间应该没问题,但我找不到任何保证在使用union时只使用被访问成员的相应位的东西。

    编辑:

    鉴于以下定义:

    typedef struct s1
    {
        int a;
    } s1;
    
    typedef struct s2
    {
        int a;
        int b;
    } s2;
    
    union u1
    {
        s1 a;
        s2 b;
    };
    

    这是合法的吗?

    union u1 *u = malloc(sizeof(s1));
    u->a.a = 3;
    printf("s1.a=%d\n", u->a.a);
    printf("s2.a=%d\n", u->b.a);
    

1 个答案:

答案 0 :(得分:2)

我认为你误解了指向联合的东西。

使用示例代码的一部分(您应该在问题正文中使用)

union u1
{
    s1 a;
    s2 b;
};

然后,如果你有

union u1 my_union;

保证&my_union等于例如&my_union.a &my_union.b

关于

union u1 *u = malloc(sizeof(s1));
u->a.a = 3;
printf("s1.a=%d\n", u->a.a);
printf("s2.a=%d\n", u->b.a);

这只能起作用,原因有二:使用联合会允许使用类型 - 双关语,u->a.au->b.a的大小完全相同且位置完全相同。我认为它的方式是技术上它是UB但是因为其他要求而起作用。

如果您尝试访问u->b.b,则可以保证UB。