我在enum
和unions
上阅读了一些幻灯片,其中一张幻灯片说:
您必须始终阅读您编写的最后一个元素。
然后是以下代码:
union Value {
int int_value;
float float_value;
char *str_value;
};
int main(int argc, char *argv[]) {
union Value v;
v.str_value = "hi";
v.int_value = 100;
printf("v = %s\n", v.str_value); /* undefined behavior! */
}
我们总是必须阅读我们写的最后一个元素是什么意思?为什么要访问union str_value
未定义行为的字段v
?
答案 0 :(得分:1)
工会背后的概念如下: 它是一个"结构"它占用了包含的最大(内存方面)数据类型的大小。
1
union将占用1 int的大小,意味着4/8字节,具体取决于计算机。这意味着char和number将共享相同的空间。这意味着如果您执行以下操作:
union myunion
{
char letter;
int number;
};
您可能会跳过联合中的其余变量。这意味着当你试着拿起这封信时,价值就不会是' a'了。 它不是未定义的行为,只是你踩着其余的变量(工会后面的整点),你实际上可以根据联合中的字节分布知道char值是什么。这就是为什么它被解释为只读取你写的最后一个元素,因为其余元素可能被修改。
答案 1 :(得分:1)
另一种看待这种情况的方法是,由于元素共享相同的内存空间,因此联合(与常规结构不同)一次只能保存一个值。您的程序需要在任何时候跟踪哪一个有效。
因此,当您分配(或“写入”)int_value
时,您将覆盖str_value
也使用的内存。联合的内容现在只作为int有意义;如果您尝试使用str_value
阅读它,您将获得无意义的结果。或者在这种情况下甚至是崩溃,因为你试图跟随一个没有任何意义的指针。