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

Allocating memory for unions and difference between union pointer and union of pointers

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

  1. 指向联合体的指针和包含指向其元素的指针的联合体之间有什么区别(除了语法上的区别)吗? this 示例中生成的程序集是相同的。
  2. 只要我从不访问其他成员,是否允许只为其中一个成员(不是最大的成员)分配内存?

关于第2个问题,C89草案6.5.2.1说:

The size of a union is sufficient to contain the largest of its members - The value of-at most one of the members can be stored in a union object at any time. A pointer to a union object suitably converted points to each of its members (or if a member is a bit-field. then to the unit in which it resides) and vice versa.

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

编辑:

给定以下定义:

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

我认为您误解了 pointer-to-union 这件事。

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

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

这仅适用于两个原因:Type-punning 允许使用并集,并且 u->a.au->b.a 大小完全相同且位置完全相同。我的看法是,从技术上讲它是 UB,但由于其他要求而起作用。

如果您尝试访问 u->b.b UB 将得到保证。