首先來(lái)看個(gè)栗子
#include<stdio.h>
struct CYStruct{
int a; //4
double b; //8
char c ; //1
short d; //2
}Mystruct;
int main ()
{
printf ("===%d==",sizeof(Mystruct);
return 0;
}
打印結(jié)果:===24==
我們知道在64位系統(tǒng)中拳亿,int是4字節(jié) double是8字節(jié) char是1字節(jié)对供,short是2字節(jié),加一起不是15字節(jié)么卿城?打印的結(jié)果卻是24字節(jié)。
這就是因?yàn)閮?nèi)存對(duì)齊铅搓,不僅僅是因?yàn)?字節(jié)對(duì)齊瑟押,下面會(huì)講內(nèi)存對(duì)齊的原則。
注:本文討論的內(nèi)容均是在64位系統(tǒng)下星掰。
What?
一多望、首先我們來(lái)認(rèn)識(shí)下什么是內(nèi)存對(duì)齊。
計(jì)算機(jī)中內(nèi)存空間是按照byte劃分的蹋偏,從理論上講似乎對(duì)任何類型的變量的訪問(wèn)可以從任何地址開始,但實(shí)際情況是:在訪問(wèn)特定類型變量的時(shí)候通常在特定的內(nèi)存地址訪問(wèn)至壤,這就需要對(duì)這些數(shù)據(jù)在內(nèi)存中存放的位置有限制威始,各種類型數(shù)據(jù)按照一定的規(guī)則在空間上排列,而不是順序的一個(gè)接一個(gè)的排放像街,這就是對(duì)齊黎棠。
內(nèi)存對(duì)齊是編譯器的管轄范圍。表現(xiàn)為:編譯器為程序中的每個(gè)“數(shù)據(jù)單元”安排在適當(dāng)?shù)奈恢蒙稀?/p>
why镰绎?
二脓斩、為什么需要內(nèi)存對(duì)齊
參考百度百科
1、平臺(tái)原因(移植原因):不是所有的硬件平臺(tái)都能訪問(wèn)任意地址上的任意數(shù)據(jù)的畴栖;某些硬件平臺(tái)只能在某些地址處取某些特定類型的數(shù)據(jù)随静,否則拋出硬件異常。
2、性能原因:數(shù)據(jù)結(jié)構(gòu)(尤其是棧)應(yīng)該盡可能地在自然邊界上對(duì)齊燎猛。原因在于恋捆,為了訪問(wèn)未對(duì)齊的內(nèi)存,處理器需要作兩次內(nèi)存訪問(wèn)重绷;而對(duì)齊的內(nèi)存訪問(wèn)僅需要一次訪問(wèn)沸停。
現(xiàn)在假如沒(méi)有進(jìn)行內(nèi)存對(duì)齊。
如上圖栗子昭卓,如果需要獲取b愤钾,需要在內(nèi)存中多次偏移讀取,才能找到B候醒。如果有內(nèi)存對(duì)齊能颁,現(xiàn)在只要偏移間隔為B所占內(nèi)存的倍數(shù)查找即可。大大減少了查找成員所需要的時(shí)間火焰。
How?
三劲装、內(nèi)存對(duì)齊原則
1:數(shù)據(jù)成員對(duì)?規(guī)則:結(jié)構(gòu)(struct)(或聯(lián)合(union))的數(shù)據(jù)成員,第
一個(gè)數(shù)據(jù)成員放在offset為0的地方昌简,以后每個(gè)數(shù)據(jù)成員存儲(chǔ)的起始位置要
從該成員大小或者成員的子成員大小(只要該成員有子成員占业,比如說(shuō)是數(shù)組,
結(jié)構(gòu)體等)的整數(shù)倍開始(比如int為4字節(jié),則要從4的整數(shù)倍地址開始存
儲(chǔ)纯赎。 min(當(dāng)前開始的位置mn)m=9n=4
9 10 11 12
2:結(jié)構(gòu)體作為成員:如果一個(gè)結(jié)構(gòu)里有某些結(jié)構(gòu)體成員,則結(jié)構(gòu)體成員要從
其內(nèi)部最大元素大小的整數(shù)倍地址開始存儲(chǔ).(struct a里存有struct b,b
里有char,int ,double等元素,那b應(yīng)該從8的整數(shù)倍開始存儲(chǔ).)
3:收尾工作:結(jié)構(gòu)體的總大小,也就是sizeof的結(jié)果,.必須是其內(nèi)部最大成員的整數(shù)倍.不足的要補(bǔ)?谦疾。
現(xiàn)在我們來(lái)對(duì)著上面的原則算一下上面的栗子
struct CYStruct{
int a; //4 [0-3]
double b; //8 [8-15]
char c ; //1 [16]
short d; //2 [18-19]
}Mystruct; //最大成員內(nèi)存為8字節(jié),必須是8的倍數(shù)犬金,所以補(bǔ)齊是24字節(jié)念恍。
這里附上字節(jié)占用表,當(dāng)然32位和64位還是有區(qū)別的晚顷。總結(jié)
內(nèi)存對(duì)齊就是制定一定的規(guī)則峰伙,用空間換時(shí)間,讓系統(tǒng)更快的獲取所需要的內(nèi)存该默。