C++成员对齐方式探讨
本文參考了《高質(zhì)量程序設(shè)計(jì)指南——C++/C語(yǔ)言》一書
有不妥之處懇請(qǐng)指正
一、自然對(duì)齊
某些基于RISC(精簡(jiǎn)指令集)的CPU比方SPARC、PowerPC等。採(cǎi)用高字節(jié)和高字在低地址存放、低字節(jié)和低字在高地址存放的大端模式存儲(chǔ)。而且把最高字節(jié)的地址作為變量的首地址。
在這樣的自然的存儲(chǔ)格式中,要求變量在內(nèi)存中的存放位置必須自然對(duì)齊,否則CPU會(huì)報(bào)告異常。所謂自然對(duì)齊,就是基本數(shù)據(jù)類型(主要是short、int、double)的變量不能簡(jiǎn)單地存儲(chǔ)于內(nèi)存中的隨意地址處。它們的起始地址必須可以被它們的大小整除。
比如。在32位平臺(tái)下,int和指針類型變量的地址應(yīng)該能被4整除。而short變量的地址應(yīng)該都是偶數(shù),bool和char則沒(méi)有要求。所以。基于這樣的CPU架構(gòu)的平臺(tái),編譯器將依照自然對(duì)齊的要求來(lái)為每一個(gè)變量生成邏輯地址,C++/C編譯器亦如此。
而Intel系列CPU採(cǎi)用小端模式來(lái)存放基本類型變量,即低字節(jié)和低字在低地址存放、高字節(jié)和高字在高地址存放。而且把最低字節(jié)的地址作為變量的首地址。在Intel系列CPU這樣的硬件平臺(tái)上。并不嚴(yán)格要求基本數(shù)據(jù)類型變量在內(nèi)存中必須自然對(duì)齊,相同也不會(huì)要求復(fù)合類型變量必須自然對(duì)齊。可是VC++在處理程序時(shí),為了提高CPU的處理速度,對(duì)復(fù)合類型變量做了成員對(duì)齊處理。
二、成員對(duì)齊
VC++在處理復(fù)合數(shù)據(jù)類型成員變量時(shí)默認(rèn)遵循下面三種原則:
(1)??? 復(fù)合類型對(duì)象的首地址要能被占用字節(jié)數(shù)最多的成員變量的字節(jié)數(shù)整除。
(2)??? 復(fù)合類型對(duì)象占用的內(nèi)存空間大小要能被占用字節(jié)數(shù)最多的成員變量的字節(jié)數(shù)整除。
(3)??? 各成員變量存放的起始地址相對(duì)于復(fù)合結(jié)構(gòu)的起始地址的偏移量必須為該變量的類型所占用的字節(jié)數(shù)的倍數(shù)。
舉比例如以下:
struct exm
{
?????? bool a;
?????? double b;
?????? bool c;
};
它是怎么存儲(chǔ)的?
首先,在內(nèi)存中找一個(gè)能被8整除的起始地址。然后分配24個(gè)字節(jié)。
為什么是24個(gè)而不是10個(gè)?或者是16個(gè)?
這是由于原則(3)的緣故,變量b占8個(gè)字節(jié),那么它相對(duì)于結(jié)構(gòu)的起始地址的偏移量必須為8的倍數(shù),因此盡管a僅僅占一個(gè)字節(jié),但后面會(huì)補(bǔ)上7個(gè)字節(jié)。
那么為什么變量c也占8個(gè)字節(jié)啊?這是由于原則(2)的緣故。由于在結(jié)構(gòu)體exm中。占用字節(jié)數(shù)最多的是變量b。8個(gè)字節(jié),所以exm占用的空間大小應(yīng)能被8整除,如今a和b已經(jīng)占用16個(gè)字節(jié)了,而c至少要占用一個(gè)字節(jié),因此會(huì)在c后補(bǔ)上7個(gè)字節(jié),變成24個(gè)字節(jié)。
把exm成員調(diào)換一下。變?yōu)?#xff1a;
struct exm
{
?????? double b。
?????? bool a。
?????? bool c;
};
它的大小就變成16個(gè)字節(jié)了。
當(dāng)然,我們也能夠在程序中指定對(duì)齊方式。這時(shí)上述原則將不再成立。假設(shè)在程序中指定對(duì)齊方式。則對(duì)于復(fù)合結(jié)構(gòu)中的變量,假設(shè)占用空間不足指定對(duì)齊字節(jié)。且假設(shè)依照默認(rèn)對(duì)齊方式占用的空間將比指定的對(duì)齊方式大,則將按指定對(duì)齊方式補(bǔ)足,比如:
#pragmapack(4) //依照4字節(jié)邊界對(duì)齊
struct exm
{
?????? bool a;
?????? double b;
?????? bool c;
};
在VS2010中,它占用16個(gè)字節(jié)空間。
分析:變量a假設(shè)依照默認(rèn)對(duì)齊方式要占8位,但它本身是bool型變量,占一位,指定對(duì)齊方式為4字節(jié)對(duì)齊,則a將被補(bǔ)齊為4字節(jié)。同理變量c也一樣。
把exm成員換一下位置:
#pragmapack(4) //依照4字節(jié)邊界對(duì)齊
struct exm
{
?????? double b;
?????? bool a;
?????? bool c。
};
則exm占12位。
總結(jié)
以上是生活随笔為你收集整理的C++成员对齐方式探讨的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: (转)基于MVC4+EasyUI的Web
- 下一篇: 5G研发大幕开启 终端硝烟已燃