結(jié)構(gòu)體內(nèi)存對(duì)齊

為什么存在內(nèi)存對(duì)齊
1.平臺(tái)原因(移植原因)
不是所有的硬件都能任意訪問(wèn)任意地址上的任意數(shù)據(jù)的,某些硬件平臺(tái)只能在某些地址處取某些特定類(lèi)型的數(shù)據(jù),否則拋出異常
2.性能原因
數(shù)據(jù)結(jié)構(gòu)(尤其是棧)應(yīng)該盡可能的在自然邊界上對(duì)齊,為了訪問(wèn)未對(duì)齊的內(nèi)存,CPU需要訪問(wèn)內(nèi)存2次;訪問(wèn)對(duì)齊后的內(nèi)存,CPU只需要訪問(wèn)內(nèi)存1次。
在Windows的VS中默認(rèn)對(duì)齊值為8
Linux中(GCC編譯器)默認(rèn)對(duì)齊值為8

在內(nèi)存中我們一般讀取數(shù)據(jù)不是按內(nèi)存來(lái)讀取,一般都是按內(nèi)存塊來(lái)讀取。
未對(duì)齊的情況下,當(dāng)需要訪問(wèn)int類(lèi)型的數(shù)據(jù)時(shí),需要CPU訪問(wèn)2次內(nèi)存塊(內(nèi)存塊1和內(nèi)存塊2)
對(duì)齊的情況下,當(dāng)訪問(wèn)int類(lèi)型的數(shù)據(jù)時(shí),只需要CPU訪問(wèn)1次內(nèi)存塊(內(nèi)存塊2)即可
是一種空間換時(shí)間的做法
結(jié)構(gòu)體內(nèi)存對(duì)齊規(guī)則
第一個(gè)成員在結(jié)構(gòu)體變量偏移量為0的地址
有效對(duì)齊值為Min(編譯器默認(rèn)對(duì)齊值,結(jié)構(gòu)體中成員數(shù)據(jù)類(lèi)型中占用內(nèi)存最大值)
其他成員要對(duì)齊到Min(有效對(duì)齊值,該成員數(shù)據(jù)類(lèi)型的內(nèi)存大?。?/strong>的整數(shù)倍
?結(jié)構(gòu)體總大小為有效對(duì)齊值的整數(shù)倍
如果嵌套結(jié)構(gòu)體,有效對(duì)齊值為Min(編譯器默認(rèn)對(duì)齊值,Max(嵌套結(jié)構(gòu)體中成員數(shù)據(jù)類(lèi)型中占用內(nèi)存最大值,結(jié)構(gòu)體中成員一數(shù)據(jù)類(lèi)型占用內(nèi)存、結(jié)構(gòu)體中成員二數(shù)據(jù)類(lèi)型占用內(nèi)存……結(jié)構(gòu)體中成員N數(shù)據(jù)類(lèi)型占用內(nèi)存))
如果嵌套共同體,有效對(duì)齊值為Min(編譯器默認(rèn)對(duì)齊值,Max( Max(共同體內(nèi)成員一、共同體內(nèi)成員二……共同體內(nèi)成員N),結(jié)構(gòu)體中成員一數(shù)據(jù)類(lèi)型占用內(nèi)存、結(jié)構(gòu)體中成員二數(shù)據(jù)類(lèi)型占用內(nèi)存……結(jié)構(gòu)體中成員N數(shù)據(jù)類(lèi)型占用內(nèi)存))
共用體所占內(nèi)存大小:Max(共同體內(nèi)成員一、共同體內(nèi)成員二……共同體內(nèi)成員N)
舉例
#pramga pack(n)
告訴編譯器字節(jié)對(duì)齊方式為n字節(jié)對(duì)齊
結(jié)構(gòu)體中最大的成員數(shù)據(jù)類(lèi)型占用4字節(jié),有效對(duì)齊值為Min(8,4)=4;char為第一個(gè)成員,應(yīng)在結(jié)構(gòu)體偏移量為0的地址,占用1字節(jié);int占用4字節(jié),要對(duì)齊在Min(8,4)=4的整數(shù)倍位置,即4的位置(4,5,6,7);char占用1字節(jié),要對(duì)齊在Min(8,1)=1的整數(shù)倍位置,即8位置;因?yàn)?strong>結(jié)構(gòu)體總大小為有效對(duì)齊值的整數(shù)倍,所以結(jié)構(gòu)體的大小應(yīng)為12(0~11)

結(jié)構(gòu)體s1中最大數(shù)據(jù)類(lèi)型結(jié)構(gòu)為int占用4字節(jié),結(jié)構(gòu)體s2的有效對(duì)齊值為Min(8,Max(4,1,8))=8;char為第一個(gè)成員,應(yīng)在結(jié)構(gòu)體偏移量為0的地址,占用1字節(jié);嵌套結(jié)構(gòu)體s1(占用12字節(jié))要對(duì)齊在Min(8,4)=4的整數(shù)倍,即4(4-15);double占用8字節(jié),要對(duì)齊在Min(8,8)的整數(shù)倍位置,即16(16-23);因?yàn)?strong>結(jié)構(gòu)體總大小為有效對(duì)齊值的整數(shù)倍;此時(shí)結(jié)構(gòu)體內(nèi)存大小為24,滿足要求。

共同體w中最大數(shù)據(jù)類(lèi)型占用內(nèi)存為Max(4,8)=8;結(jié)構(gòu)體s1的有效對(duì)齊值為Min(4,Max(8,1,4,2))= 4;char為第一個(gè)成員,應(yīng)在結(jié)構(gòu)體偏移量為0的地址,占用1字節(jié);int占用4字節(jié),要對(duì)齊在Min(4,4)=4的整數(shù)倍位置,即4的位置(4,5,6,7);共同體w占Max(4,8)=8字節(jié),要對(duì)齊在Min(4,12)=4的整數(shù)倍位置,即8的位置(8-15);short占2字節(jié),要對(duì)齊在Min(4,2)=2的整數(shù)倍為止,即16(16-17);因?yàn)?strong>結(jié)構(gòu)體總大小為有效對(duì)齊值的整數(shù)倍;所以結(jié)構(gòu)體s1的大小需要補(bǔ)位到4的整數(shù)倍,即20字節(jié)。

?