为什么我们必须始终阅读我们用C联合写的最后一个元素?

时间:2016-03-19 16:10:33

标签: c undefined-behavior

我在enumunions上阅读了一些幻灯片,其中一张幻灯片说:

  

您必须始终阅读您编写的最后一个元素。

然后是以下代码:

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

2 个答案:

答案 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阅读它,您将获得无意义的结果。或者在这种情况下甚至是崩溃,因为你试图跟随一个没有任何意义的指针。