结构体对齐
結(jié)構(gòu)體對(duì)齊
C/C++數(shù)據(jù)對(duì)齊
為了避免混淆,做如下規(guī)定,以下代碼若不加特殊說(shuō)明都運(yùn)行于32位平臺(tái),結(jié)構(gòu)體的默認(rèn)對(duì)齊值是8,各數(shù)據(jù)類型所占字節(jié)數(shù)分別為
char占一個(gè)字節(jié)
int占四個(gè)字節(jié)
double占八個(gè)字節(jié)。
兩個(gè)例子
請(qǐng)問(wèn)下面的結(jié)構(gòu)體大小是多少?
struct Test {char c ;int i ; };這個(gè)呢?
struct Test1 {int i ;double d ;char c ; };在公布答案之前先看一下對(duì)齊的規(guī)則。
對(duì)齊規(guī)則
一般來(lái)說(shuō),結(jié)構(gòu)體的對(duì)齊規(guī)則是先按數(shù)據(jù)類型自身進(jìn)行對(duì)齊,然后再按整個(gè)結(jié)構(gòu)體進(jìn)行對(duì)齊,對(duì)齊值必須是2的冪,比如1,2, 4, 8, 16。如果一個(gè)類型按n字節(jié)對(duì)齊,那么該類型的變量起始地址必須是n的倍數(shù)。比如int按四字節(jié)對(duì)齊,那么int類型的變量起始地址一定是4的倍數(shù),比如0x0012ff60,0x0012ff48等。
?
數(shù)據(jù)自身的對(duì)齊
數(shù)據(jù)自身的對(duì)齊值通常就是數(shù)據(jù)類型所占的空間大小,比如int類型占四個(gè)字節(jié),那么它的對(duì)齊值就是4
整個(gè)結(jié)構(gòu)體的對(duì)齊
整個(gè)結(jié)構(gòu)體的對(duì)齊值一般是結(jié)構(gòu)體中最大數(shù)據(jù)類型所占的空間,比如下面這個(gè)結(jié)構(gòu)體的對(duì)齊值就是8,因?yàn)閐ouble類型占8個(gè)字節(jié)。
struct Test2 {int i ;double d ; };例子答案
有了上面的基礎(chǔ),再回過(guò)頭去看看一開(kāi)始的兩個(gè)例子
先看結(jié)構(gòu)體Test
1 c是char類型,按1個(gè)字節(jié)對(duì)齊
2 i是int類型,按四個(gè)字節(jié)對(duì)齊,所以在c和i之間實(shí)際上空了三個(gè)字節(jié)。
整個(gè)結(jié)構(gòu)體一共是1 + 3(補(bǔ)齊)+ 4 = 8字節(jié)。
再看Test1
i是int類型,按4字節(jié)對(duì)齊
d是double類型,按8字節(jié)對(duì)齊,所以i和d之間空了4字節(jié)
c是char類型,按1字節(jié)對(duì)齊。
所以整個(gè)結(jié)構(gòu)體是 4(i) + 4(補(bǔ)齊)+ 8(d) + 1(c) =? 17字節(jié),注意!還沒(méi)完,整個(gè)結(jié)構(gòu)體還沒(méi)有對(duì)齊,因?yàn)榻Y(jié)構(gòu)體中空間最大的類型是double,所以整個(gè)結(jié)構(gòu)體按8字節(jié)對(duì)齊,那么最終結(jié)果就是17 + 7(補(bǔ)齊) = 24字節(jié)。
書(shū)寫(xiě)結(jié)構(gòu)體的建議
我們對(duì)Test1做一點(diǎn)改動(dòng)
struct Test1 {char c ;int i ;double d ; };這時(shí)Test1的大小就變成了16,而不是24了,節(jié)省了8個(gè)字節(jié)!可見(jiàn)結(jié)構(gòu)體中成員的書(shū)寫(xiě)順序?qū)Y(jié)構(gòu)體大小的影響還是很大的,一個(gè)好的建議是,按照數(shù)據(jù)類型由小到大的順序進(jìn)行書(shū)寫(xiě)。http://www.cnblogs.com/graphics/archive/2010/08/12/1797953.html
總結(jié)
- 上一篇: 结构体中的malloc 与 free
- 下一篇: 更改结构体的内存字节对齐方式--经典