2010-05-30 52 views
5

好吧,我有我的C一個struct ++程序是這樣的:含無符號的字符和INT的bug C++結構

struct thestruct 
{ 
unsigned char var1; 
unsigned char var2; 
unsigned char var3[2]; 
unsigned char var4; 
unsigned char var5[8]; 
int var6; 
unsigned char var7[4]; 
}; 

當我使用這個結構,3個隨機字節獲得「var6」前添加,如果我刪除「var5」它仍然在「var6」之前,所以我知道它總是在「var6」之前。

但是,如果我刪除了「var6」,那麼3個額外的字節消失了。

如果我只使用一個帶int的結構體,那麼沒有額外的字節。

所以在unsigned char和int之間似乎有衝突,我該如何解決這個問題?

回答

6

編譯器可能使用其默認對齊選項,其中大小的成員X的存儲器邊界由整除對齊x

取決於你的編譯器,你可以使用一個#pragma directive影響這種行爲,例如:

#pragma pack(1) 

將關閉默認的對齊方式在Visual C++:

指定的值,以字節爲單位,用於包裝。爲Ñ的缺省值是8。有效值是1,2,4,8和16。一個部件的對準將是一個邊界要麼是一個的Ñ倍數或的大小的倍數上該成員,以較小者爲準。

注意,對於低級別的CPU性能方面的原因,它通常是最好的嘗試,以您的數據成員對齊,使他們落入對齊邊界上。某些CPU架構需要對齊,而另一些CPU架構(如Intel x86)容忍未對齊,性能下降(有時非常顯着)。

+0

謝謝你的工作 – powerfear 2010-05-30 04:33:10

4

你說的是填充字節嗎?這不是一個錯誤。正如C++標準所允許的,編譯器正在添加填充以保持成員aligned。這對於某些體系結構是必需的,並且會大大提高其他體系的性能。

5

你的數據結構是aligned讓你的INT落在單詞boundries,這對於你的目標可能是32或64位。
您可以重新組織你的結構像這樣,使這不會發生:

struct thestruct 
{ 
int var6; 
unsigned char var1; 
unsigned char var2; 
unsigned char var3[2]; 
unsigned char var4; 
unsigned char var5[8]; 
unsigned char var7[4]; 
}; 
+0

好的調用重組結構,比使用編譯器相關的打包編譯指示/屬性要好得多。 – 2010-05-30 11:49:35

+0

雖然它仍然是實現定義的。 – 2010-12-11 21:05:48

0

你有一個字節對齊問題。編譯器正在添加填充以對齊字節。請參閱this維基百科文章。

0

閱讀上data structure alignment。實質上,根據編譯器和編譯選項,您將得到不同的2的權力。

爲了避免它,單字節(符號或無符號字符)項目前移到多字節項目(INT或指針) - 儘管它仍然可能是後您的最後一個項目有

0

雖然重新安排你聲明的數據成員的順序您struct裏面是好的,但應該強調的是,通過使用#pragma小號覆蓋默認對齊和這樣一個壞主意,除非你知道自己在做什麼。根據您的編譯器和體系結構,嘗試訪問未對齊的數據(尤其是通過將地址存儲在指針中並稍後嘗試對其進行解引用)可能會輕鬆導致可怕的總線錯誤或其他未定義的行爲。