午夜视频在线网站,日韩视频精品在线,中文字幕精品一区二区三区在线,在线播放精品,1024你懂我懂的旧版人,欧美日韩一级黄色片,一区二区三区在线观看视频

分享

【轉載】union和union用sizeof看字節(jié)對齊

 開花結果 2009-11-15
union u
{
 double a;
 int b;
};
union u2
{
 char a[13];
 int b;
};
union u3
{
 char a[13];
 char b;
};
cout<<sizeof(u)<<endl; // 8
cout<<sizeof(u2)<<endl; // 16
cout<<sizeof(u3)<<endl; // 13
 
  都知道union的大小取決于它所有的成員中,占用空間最大的一個成員的大小。所以對于u來說,大小就是最大的double類型成員a了,所以sizeof(u)=sizeof(double)=8。但是對于u2和u3,最大的空間都是char[13]類型的數(shù)組,為什么u3的大小是13,而u2是16呢?關鍵在于u2中的成員int b。由于int類型成員的存在,使u2的對齊方式變成4,也就是說,u2的大小必須在4的對界上,所以占用的空間變成了16(最接近13的對界)。
  結論:復合數(shù)據(jù)類型,如union,struct,class的對齊方式為成員中對齊方式最大的成員的對齊方式。
  順便提一下CPU對界問題,32的C++采用8位對界來提高運行速度,所以編譯器會盡量把數(shù)據(jù)放在它的對界上以提高內(nèi)存命中率。對界是可以更改的,使用#pragma pack(x)宏可以改變編譯器的對界方式,默認是8。C++固有類型的對界取編譯器對界方式與自身大小中較小的一個。例如,指定編譯器按2對界,int類型的大小是4,則int的對界為2和4中較小的2。在默認的對界方式下,因為幾乎所有的數(shù)據(jù)類型都不大于默認的對界方式8(除了long double),所以所有的固有類型的對界方式可以認為就是類型自身的大小。更改一下上面的程序:
#pragma pack(2)
union u2
{
 char a[13];
 int b;
};
union u3
{
 char a[13];
 char b;
};
#pragma pack(8)
cout<<sizeof(u2)<<endl; // 14
cout<<sizeof(u3)<<endl; // 13
 
  由于手動更改對界方式為2,所以int的對界也變成了2,u2的對界取成員中最大的對界,也是2了,所以此時sizeof(u2)=14。
  結論:C++固有類型的對界取編譯器對界方式與自身大小中較小的一個。
  9、struct的sizeof問題
  因為對齊問題使結構體的sizeof變得比較復雜,看下面的例子:(默認對齊方式下)
struct s1
{
 char a;
 double b;
 int c;
 char d;
};
struct s2
{
 char a;
 char b;
 int c;
 double d;
};
cout<<sizeof(s1)<<endl; // 24
cout<<sizeof(s2)<<endl; // 16
 
  同樣是兩個char類型,一個int類型,一個double類型,但是因為對界問題,導致他們的大小不同。計算結構體大小可以采用元素擺放法,我舉例子說明一下:首先,CPU判斷結構體的對界,根據(jù)上一節(jié)的結論,s1和s2的對界都取最大的元素類型,也就是double類型的對界8。然后開始擺放每個元素。
  對于s1,首先把a放到8的對界,假定是0,此時下一個空閑的地址是1,但是下一個元素d是double類型,要放到8的對界上,離1最接近的地址是8了,所以d被放在了8,此時下一個空閑地址變成了16,下一個元素c的對界是4,16可以滿足,所以c放在了16,此時下一個空閑地址變成了20,下一個元素d需要對界1,也正好落在對界上,所以d放在了20,結構體在地址21處結束。由于s1的大小需要是8的倍數(shù),所以21-23的空間被保留,s1的大小變成了24。
  對于s2,首先把a放到8的對界,假定是0,此時下一個空閑地址是1,下一個元素的對界也是1,所以b擺放在1,下一個空閑地址變成了2;下一個元素c的對界是4,所以取離2最近的地址4擺放c,下一個空閑地址變成了8,下一個元素d的對界是8,所以d擺放在8,所有元素擺放完畢,結構體在15處結束,占用總空間為16,正好是8的倍數(shù)。
  這里有個陷阱,對于結構體中的結構體成員,不要認為它的對齊方式就是他的大小,看下面的例子:
struct s1
{
 char a[8];
};
struct s2
{
 double d;
};
struct s3
{
 s1 s;
 char a;
};
struct s4
{
 s2 s;
 char a;
};
cout<<sizeof(s1)<<endl; // 8
cout<<sizeof(s2)<<endl; // 8
cout<<sizeof(s3)<<endl; // 9
cout<<sizeof(s4)<<endl; // 16;
 
  s1和s2大小雖然都是8,但是s1的對齊方式是1,s2是8(double),所以在s3和s4中才有這樣的差異。
  所以,在自己定義結構體的時候,如果空間緊張的話,最好考慮對齊因素來排列結構體里的元素。
結論:struct 里面的元素是順序存儲的,每個元素占用的字節(jié)數(shù)根據(jù)對齊字節(jié)數(shù)N(struct 里占用字節(jié)最多的元素與CPU對齊字節(jié)數(shù)中較小的一個)進行調(diào)整.如果從左至右M個元素加起來的字節(jié)數(shù)大于N,則按從右至左舍去K個元素直至M-K個元素加起來的字節(jié)數(shù)小于等于N,如果等于N則不用字節(jié)填充,小于N則把M-K-1的元素填充直至=N.

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多