2011-08-27 27 views
7

Bir sendikanın boyutunu şu şekilde yazdığımda:Sendikamın büyüklüğü neden beklediğimden daha büyük?

union u { 
    char c[5]; 
    int i; 
} un; 
union u { 
    char c[5]; 
    int i; 
} un; 

bunu kullanarak:

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    printf("size of union = %d ",sizeof(un)); 
    return 0; 
} 

Visual C++ kullanarak 8 cevabı alıyorum, ama bekledim 5. Neden?

Aynı örnek için,

int i1 = 0x98761234; 
un.i = i1; 
printf("\n un.c[0] = %x ",un.c[0]); 
printf("\n un.c[1] = %x ",un.c[1]); 
printf("\n un.c[2]= %x ",un.c[2]); 
printf("\n un.c[3] = %x ",un.c[3]); 
printf("\n un.c[4] = %x ",un.c[4]); 
printf("size of union = %d ",sizeof(un)); 

un.c[0] = 34; 
un.c[1] = 12; 
un.c[2] = 76; 
un.c[3] = ffffff98; 

gibi sonuçları aldım neden 6fs un.c [3]

cevap

11

sizeof operatör her hala doğru olarak hizalanmış şekilde bu tür bir dizi ayrı elemanlar için gerekli herhangi bir doldurma içeren bir değişken veya türü boyutunu üretir. Birliğiniz bir int üyesine sahip olduğundan, 4 baytlık hizalanmış olması gerekir, bu nedenle "doğal" boyutu 4 bayt'ın sonraki katına yuvarlanır. Eğer imzalı char ile derleme çünkü


ffffff98 olduğunu. %x'u unsigned int olmayan bir argümanı kullanarak tanımsız davranışa neden olur; Gördüğünüz şey bazen oturum açma uzantısı olarak adlandırılır. Takma adınızın sonucu,, -104 olarak yeniden yorumlanmıştır. Bu, int (bu varsayılan argüman promosyonları olarak adlandırılır) ve unsigned int olarak adlandırıldığında int 0xffffff98 haline getirildiğinde int -104 olarak adlandırılır.

1

Derleyici, bellek girişlerini hızlandırmak için yapılara, birliklere ve sınıflara istediği yerde dolgu ekleyebilir. Bunun etkisini görüyorsun. Visual C++ için, dolgu genellikle en büyük üye türünün boyutunun katlarıdır. Bu örnekte, en büyük üye bir int'dir, bu nedenle, toplam boyutu 8 yapmak için 3 kullanılmayan bayt ile birleşimi destekler.

+0

için birkaç bayt ekler büyük üye 5 bayt olan c. Derleyici, dolgu ekleyerek bunu 8'e kadar çevirir. Sistem 8 baytlık tamsayı kullanıyorsa, birleştirme boyutu için 8 kullanılır. –

+0

@Brian sana "büyük üyesi türü" yorumunu kısa bir süre önce benim cevap değişti, bir int daha net göstermek için. –

+1

Ben hala cevap net veya doğru olduğunu düşünmüyorum, bilmiyorum. En büyük üyenin bir int olduğunu söylüyorsun, ama değil. 5 karakterlik bir dizidir. 5> 4 yana o 8. –

3

Sendikanızın uyumu, üyelerinden herhangi birinin en büyük hizalaması olmalıdır. Bu 4'tür. Bu nedenle, birliğin boyutu o boyuta hizalanmalıdır. 5 (c, birliğin en büyük üyesi olduğu gibi) olabilir, ancak bir bütün olarak hizalama 4 olduğu için, birliğin boyutu, 8

için olduğunu unutmayın. VC++. Standart, özellikle gerektirmez. Her ne kadar VC++ 'nın ihtiyaç duyduğu gibi ped tiplerine de uygulama sağlar. GCC farklı bir şey yapabilir ve bu davranışı değiştirmek için kullanabileceğiniz derleme zamanı anahtarları olabilir.

0

Önerileriniz için teşekkür ederiz. Bunu çok sayıda örnekle denedim ve birleştirme boyutunun (maksimum elemanın boyutu) + dolguya (kullanılan en yüksek veri türü boyutuna bağlı) eşdeğer olduğunu düşünüyorum.

2

enter image description here Derleyici 4 baytlık tamsayı varsayarsak hizalama

İlgili konular