2012-03-22 89 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