c - 为 union 分配内存以及 union 指针和指针 union 之间的区别

标签 c pointers casting unions

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

  1. 指向 union 的指针和包含指向其元素的指针的 union 之间有什么区别(除了语法之外)吗? this中生成的程序集示例是相同的。
  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.

因此,至少在正确转换时,只为其中一个成员分配空间应该没问题,但我找不到任何东西可以保证在使用 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);

最佳答案

我认为您误解了指向 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);

这之所以有效,有两个原因:允许使用 union 进行类型双关,并且 u->a.au->b.a 的大小完全相同,并且在完全相同的位置。我的看法是,从技术上讲它是 UB,但由于其他要求而有效。

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

关于c - 为 union 分配内存以及 union 指针和指针 union 之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49259777/

相关文章:

c - 如何链接到 Tcl C API 中的 tclOO 函数

c - 在 GTK+ 中禁用垂直缩放

c++ - 对字符数组中的单词进行排序

c - 将指针分配给数组的正确方法

c - free() 是否设置 errno?

c - 数组初始化时 GDB 报告 "no symbol in current context"

c - 如何从 void 指针引用和取消引用不同的数据类型?

c# - 使用 Type 对象将 Object 类型的对象转换为另一种类型

casting - Kotlin合成整数不能转换为 float 按钮

c++ - c++ 中的两个 'char*' 铸件有什么区别