1

我试图union在 Linux 环境中理解和使用 C 语言中的 a 。假设我有以下工会

union test {
    int one;
    long two;
} t1;

如果我要写入t1.one网络文件描述符(socket fd),那么额外的零将被写入 fd,因为联合选择了最大的元素,即 2;结构联合可能会变得更糟。有人可以告诉我如何克服这个问题吗?

4

3 回答 3

1

Anunion具有最大元素的大小(在这种情况下long),不像结构。通过更改one,您将覆盖 long 的前 32 位(在 32 位 OS 16 上),通过更改two整个空间将被覆盖并one丢失。

union test在 64 位操作系统上:

-      64 bit      +
│    union test    │
├──────────────────┤
│ long             │
├─────────┬────────┘
│ int     |
└─────────┘

struct test在 64 位操作系统上:

-           96 bit           +
│         struct test        │
├──────────────────┬─────────┤
│ long             │ int     │
└──────────────────┴─────────┘
于 2012-07-09T19:22:52.810 回答
1

不,如果您写入test.one网络 fd,您将准确写入sizeof (int)字节。 test.one是一个int对象;只要您不访问整个工会,它恰好是工会成员的事实是无关紧要的。

如果您编写整个联合,那么您当然会编写联合的完整大小,至少是其最大成员的大小。

所以不要那样做。

跟踪工会的哪个成员是当前的(即,您最近为哪个成员分配了值),然后只使用该成员。

再说一次,鉴于您给我们的信息很少,不清楚使用联合是否有意义。

于 2012-07-09T18:59:10.560 回答
1

如果我要将 test.one 写入网络 fd,那么额外的零将写入 fd

尽管将写入额外的字节是正确的,但这些字节的内容不一定全为零:它是未定义的。通常,通过其他字段读取属于您已写入某些数据的区域之外的联合字节是未定义的行为。如果要控制写入的数据量,则需要提供要写入的特定类型。

于 2012-07-09T18:50:00.127 回答