2012-03-22 88 views
4

我想知道是否联合变量将如下的结构变量或不被初始化...工会初始化

#include<stdio.h> 
int main(void) 
{ 
struct a 
{ 
int i; 
char c; 
}; 
struct a ob={4}; 
printf("%d",ob.c); 

}
上述代码给出0作为输出..
所以当i是初始化c也得到初始化..
在下面的代码...如果工会成员整数也获得了字符数组的初始化这段代码会给出输出515 ...
(我通过为联合分配内存变量使用malloc ..它工作正常。)

#include<stdio.h> 
int main(void) 
{ 
union a 
{ 
int i; 
char c[2]; 
}; 
union a ob; 
ob.ch[0]=3; 
ob.ch[1]=2; 
printf("%d",ob.i); 
return 0; 
} 

但是没有分配内存是否可以初始化int i(在这个代码中int i的十六进制值设置为0x990203)。
我认为99是显示了较高的位不intialized结果..
对吗?..

+0

从您未写入的联盟字段中读取未定义的行为。你*可以*看到任意数据,它不值得你的特定编译器以某种方式做它。 – dasblinkenlight 2012-03-22 14:51:53

+2

@dasblinkenlight:读取你没有写入的成员是已定义的行为 - 但是,如果该成员由没有参与上次存储的字节表示(即,如果被访问的成员的大小大于用于最后一次存储),行为是未指定的;有关详细信息,请参阅http://stackoverflow.com/a/8513748/48015 – Christoph 2012-03-22 14:54:57

+0

您可能是对的,请查看编译器的汇编输出以确保。 – Gowtham 2012-03-22 14:54:58

回答

2

从工会 其他的成员比一个最近写入 课外阅读您最近写入的成员的“字节占用空间”会导致 未定义的 未指定的行为。在写完之后,您不应该阅读i:无论您看到什么,都有非便携垃圾。

编辑1编辑响应Cristoph的评论。

+3

这是一个常见的误解 - 从您没有写入最后的工会成员中读取仅在C++中是非法的;然而,如果最后一个商店发生在一个较小的*一个 – Christoph 2012-03-22 15:00:50

+0

中,则成员的值是**未指定的。是的,如果对象的内容解释为您正在访问的类型是一个类型陷阱表示。首先,这种陷阱代表现在很少见,其次,你真的不幸看到它。 – 2012-03-22 15:04:28

+0

@Christoph感谢您的纠正!我已经走出“纯C”世界足够长的时间,开始认为C是C++的一个子集:) – dasblinkenlight 2012-03-22 15:08:40

1

我认为99是显示了较高的位不 intialized ..我是正确的吗?结果..

正确的,因为你只在你的第二个例子分配到两个字节明确,所以整数的两个字节保持未初始化。在第一个例子分配4i,它是一个整数,股与c一个字节。但是,如果两个工会成员属于同一类型,那么假设两者都将被初始化是正确的。此外,分配给工会的空间是其最大的成员因此假定一些i的字节时,分配给c[x]不会是错误会改变所占用的空间。

您可能会看到不同的初始化方法,在不同的范围和上下文未初始化的字节不同的值是不相关的,具体的情况,而不是定义。但是,我不能评论515,因为我不清楚你是如何得到这个价值的。

+0

您可以评论有关使用malloc将int的值留给515. – cdummy 2012-03-22 15:38:38

+0

@cdummy,更新了答案 – perreal 2012-03-22 15:49:46

1

如果新值恰好是int类型的陷阱表示(罕见),那么通过char的分配可能会导致未定义的行为。

您与union例子是初始化,但只有一个任务,并因此仅改变正是您要访问的字节和其他住宿非特异性值。对于工会它始终是一个好主意,做的最广泛的成员东西一个初始化像

union a ob = { .i = 0 }; 

因此,你能保证你的对象的所有字节由0初始化。

+0

可以你对使用malloc的评论会把int的值留给515. – cdummy 2012-03-22 15:38:58

+0

@cdummy,如果你没有初始化变量(在堆栈上或者用malloc分配),那么恰好在那里的任何值都被用于int价值。这完全是任意的。只有您直接更改的两个'char'才具有您控制的值。 – 2012-03-22 15:44:35

+0

是否与calloc相同 – cdummy 2012-03-22 15:49:47